首页 > 解决方案 > 单击或悬停在分层透明组件上时如何防止奇怪的绘画伪影出现?

问题描述

在我的程序中,我使用的是 JLayeredPane,其中我的一层是半透明的 JPanel,即menuBarPanel.setBackground(new Color(0,0,0,200));。(我没有menuBarPanel.setOpaque(false);)然后我有另一个“子JPanel”,我添加到透明的并将不透明设置为false。一些 JTextPanes 和 JRadioButtons 添加到该子 JPanel 中,我也将 opaque 设置为 false。当我切换 JRadioButton、突出显示任何 JTextPane 文本或简单地单击 JTextPane 时,就会出现问题。当我执行任何这些操作时,奇怪的绘画伪影开始出现在这些组件上。我知道这与在半透明面板上放置完全透明的东西(不透明设置为 false)有很大关系。当我与 java 交互时尝试绘制事物时,会发生一些奇怪的事情。这是我的代码中导致问题的部分。任何帮助表示赞赏,但请详细解释。我也愿意接受更多的编码技巧(我对编程很陌生)。

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;
    }
}

用您喜欢的任何图像替换“ChessBackGround.jpg”。这是主要课程。

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);
            }
        });
    }
}

标签: javaswingjlayeredpane

解决方案


推荐阅读