0

In my program I'm using JLayeredPane where one of my layers is a semi-transparent JPanel i.e. menuBarPanel.setBackground(new Color(0,0,0,200));. (I did not menuBarPanel.setOpaque(false);) I then have a another "sub-JPanel" that I added to the transparent one and set opaque to false. A few JTextPanes and JRadioButtons are added to that sub JPanel which I set opaque to false on as well. The problem arises when I toggle a JRadioButton, highlight any of the the JTextPane text, or simply click on the JTextPane. Weird painting artifacts start appearing all over these components when I do any of these actions. I know this has a lot to do with putting something fully transparent (opaque set to false) on top of a semi-transparent panel. Something weird is happening when java is trying to paint things when I interact with them. Here is the part of my code that is causing the issue. Any help is appreciated but please explain in detail. I'm also open to more coding tips (I'm very new to programming).

package com.chess.GUI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.text.Highlighter;
public class MenuComponent
{
    private JLabel menuImageLabel;
    private BufferedImage bufferedImage; 
    private ImageIcon ic;
    private JPanel menuBarPanel;
    private JPanel subMenuSettingsPanel;
    private JTextPane gameInfoPane;
    private JTextPane toggleSplitScreenText;
    private JTextPane toggleDevModeText;
    private JLayeredPane mainLayeredPane;
    private JButton playBtn;
    private JRadioButton toggleSplitScreen;
    private JRadioButton toggleDevMode;
    private TitledBorder menuSettingsBorder;

    public MenuComponent()
    {   
        loadMenuImage();

        ic = new ImageIcon(scaleImage(bufferedImage, 1008, 756));
        mainLayeredPane = new JLayeredPane();
        menuImageLabel = new JLabel(ic);
        menuBarPanel = new JPanel();
        subMenuSettingsPanel = new JPanel();
        gameInfoPane = new JTextPane();
        toggleSplitScreenText = new JTextPane();
        toggleDevModeText = new JTextPane();
        playBtn = new JButton("PLAY");
        toggleSplitScreen = new JRadioButton();
        toggleDevMode = new JRadioButton();
        menuSettingsBorder = new TitledBorder(BorderFactory.createTitledBorder(menuSettingsBorder, "Settings", TitledBorder.LEFT, TitledBorder.TOP, new Font("Sans-serif", Font.PLAIN, 15), new Color(4, 148, 255)));

        toggleSplitScreenText.setText("Toggle Split Screen");
        toggleSplitScreenText.setFont(new Font("Sans-serif", Font.PLAIN, 18));
        toggleSplitScreenText.setOpaque(false);
        toggleSplitScreenText.setForeground(new Color(0,230,0));
        toggleSplitScreenText.setEditable(false);
        toggleSplitScreen.setOpaque(false);

        toggleDevModeText.setText("Toggle Deveveloper Mode");
        toggleDevModeText.setFont(new Font("Sans-serif", Font.PLAIN, 18));
        toggleDevModeText.setEditable(false);
        toggleDevModeText.setOpaque(false);
        toggleDevModeText.setForeground(new Color(0,230,0));
        toggleDevMode.setOpaque(false);

        subMenuSettingsPanel.setLayout(new GridBagLayout());
        subMenuSettingsPanel.setBorder(menuSettingsBorder);
        subMenuSettingsPanel.setOpaque(false);

        subMenuSettingsPanel.add(toggleSplitScreenText, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,30,14,3), 0,0));
        subMenuSettingsPanel.add(toggleSplitScreen, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,8,0), 0,0));
        subMenuSettingsPanel.add(toggleDevModeText, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,20,14,3), 0,0));
        subMenuSettingsPanel.add(toggleDevMode, new GridBagConstraints(3, 1, 1, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,8,0), 0,0));

        playBtn.setFont(new Font("Sans-serif", Font.PLAIN, 30));
        playBtn.setBackground(new Color(4, 148, 255));
        playBtn.setForeground(new Color(230, 230, 230));
        playBtn.setFocusPainted(false);
        playBtn.setBorderPainted(false);
        playBtn.addMouseListener(new MouseAdapter() {
            public void mouseEntered(MouseEvent evt) {
                playBtn.setBackground(new Color(40, 160, 255));
                playBtn.setForeground(Color.WHITE);
            }
            public void mouseExited(MouseEvent evt) {
                playBtn.setBackground(new Color(4, 148, 255));
                playBtn.setForeground(new Color(230, 230, 230));
            }
        });

        menuBarPanel.setLayout(new GridBagLayout());
        menuBarPanel.setBounds(0, 612, 1008, 144);
        menuBarPanel.setBackground(new Color(0,0,0,200));//x y wd ht  wtx  wty          anchor                     fill           margin(top,left,btm,rt) padx pady
        menuBarPanel.add(playBtn, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(8, 75, 5, 40), 115,20));
        menuBarPanel.add(subMenuSettingsPanel, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.BASELINE, GridBagConstraints.NONE, new Insets(0,0,5,75), 250,44));

        menuImageLabel.setSize(1008, 756);
        menuImageLabel.setOpaque(false);

        gameInfoPane.setBounds(768,0,260,20);
        gameInfoPane.setText("");
        gameInfoPane.setOpaque(false);
        gameInfoPane.setForeground(new Color(0,230,0));
        gameInfoPane.setFont(new Font("Sans-serif", Font.PLAIN, 12));
        gameInfoPane.setEditable(false);

        mainLayeredPane.add(menuImageLabel);
        mainLayeredPane.add(menuBarPanel,0);
        mainLayeredPane.add(gameInfoPane, 0);
    }

    public JLayeredPane getMenuPane()
    {
        return mainLayeredPane;
    }

    private void loadMenuImage()
    {
        try {
            bufferedImage = ImageIO.read(new File("ChessBackGround.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Image scaleImage(BufferedImage bi, int w, int h)
    {
        BufferedImage resizedImage = new BufferedImage(w,h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = resizedImage.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.drawImage(bi, 0, 0, w, h, null);
        g2.dispose();
        return resizedImage;
    }
}

Replace "ChessBackGround.jpg" with any image you like. This is the main class.

package com.chess.GUI;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class MainControllerGUI
{
    public MainControllerGUI()
    {
        new MainFrame();
    }
}

@SuppressWarnings("serial")
class MainFrame extends JFrame
{
    private MenuComponent mc;

    public MainFrame()
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run()
            {
                mc = new MenuComponent();
                setSize(1008,795);
                setTitle("Chess");
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                setResizable(false);
                setContentPane(mc.getMenuPane());
                setVisible(true);
            }
        });
    }
}
Jake
  • 1
  • 1
  • 1
    Swing components don't support alpha based colours - they are either opaque or transparent - not translucent. You can "fake" this, but you need to make a custom component, which, when `isOpaque` is `false` will continue to paint the background color at the desired `alpha` level – MadProgrammer Mar 08 '20 at 02:19
  • 1
    The complexity of the solution will depend on the component(s) you are trying to provide support for for [example](https://stackoverflow.com/questions/34122512/transparent-jdesktoppane/34123026#34123026), [example](https://stackoverflow.com/questions/35472993/weird-color-changes-on-hovering-on-jbutton/35473190#35473190), [example](https://stackoverflow.com/questions/43010330/jtable-autocreaterowsorter-causes-swing-to-paint-the-table-wrong/43010876#43010876) – MadProgrammer Mar 08 '20 at 02:22
  • 1
    For [example](https://stackoverflow.com/questions/18070120/java-swing-graphical-glitches-dealing-with-transparency-and-images/18074326#18074326) – MadProgrammer Mar 08 '20 at 02:22
  • 1
    Swing doesn't support transparent backgrounds. See: [Backgrounds With Transparency](https://tips4java.wordpress.com/2009/05/31/backgrounds-with-transparency/) for an explanation of the problem and a potential solution. – camickr Mar 08 '20 at 04:27

0 Answers0