Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从按钮网格绘制特定按钮_Java_Swing_Repaint_Paintcomponent - Fatal编程技术网

Java 从按钮网格绘制特定按钮

Java 从按钮网格绘制特定按钮,java,swing,repaint,paintcomponent,Java,Swing,Repaint,Paintcomponent,以下按钮网格定义为: JButton button_x = new RoundButton(); public class RoundButton extends JButton { public RoundButton(String label) { super(label); this.setContentAreaFilled(false); Dimension size = this.getPreferredSize();

以下按钮网格定义为:

JButton button_x = new RoundButton();
public class RoundButton extends JButton {

    public RoundButton(String label) {
        super(label);
        this.setContentAreaFilled(false);
        Dimension size = this.getPreferredSize();
        size.height = size.width = Math.max(size.height, size.width);
        this.setPreferredSize(size);
    }

    @Override
    protected void paintComponent(Graphics g) {
        if(!GameState.getIfComplete()) { // If the game is not complete or has just started
            this.setBorder(null);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, this.getSize().width, this.getSize().height);
            if(this.getModel().isArmed()) {
               g.setColor(Color.RED);
            }else {
                g.setColor(Color.GREEN);
            }
            g.fillOval(0,0,this.getSize().width-1,this.getSize().height-1);
            super.paintComponent(g);
        }else {
            this.setBorder(null);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, this.getSize().width, this.getSize().height);
            g.setColor(Color.WHITE);
            g.fillOval(0,0,this.getSize().width-1,this.getSize().height-1);
            super.paintComponent(g); 
        }
    }
其中,RoundButton定义为:

JButton button_x = new RoundButton();
public class RoundButton extends JButton {

    public RoundButton(String label) {
        super(label);
        this.setContentAreaFilled(false);
        Dimension size = this.getPreferredSize();
        size.height = size.width = Math.max(size.height, size.width);
        this.setPreferredSize(size);
    }

    @Override
    protected void paintComponent(Graphics g) {
        if(!GameState.getIfComplete()) { // If the game is not complete or has just started
            this.setBorder(null);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, this.getSize().width, this.getSize().height);
            if(this.getModel().isArmed()) {
               g.setColor(Color.RED);
            }else {
                g.setColor(Color.GREEN);
            }
            g.fillOval(0,0,this.getSize().width-1,this.getSize().height-1);
            super.paintComponent(g);
        }else {
            this.setBorder(null);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, this.getSize().width, this.getSize().height);
            g.setColor(Color.WHITE);
            g.fillOval(0,0,this.getSize().width-1,this.getSize().height-1);
            super.paintComponent(g); 
        }
    }
}

目前所有的按钮都被涂成绿色,但在一定条件下,我想把特定的按钮涂成白色,这是else部分的代码。例如when!GameState.getIfComplete返回false我想把第一列中的按钮画成白色。因此,我将重绘称为:

但这不管用!在第一列中,其他一些按钮也被涂成白色。为什么呢


这个电话怎么了?如何绘制一个特定的按钮?

问题在于对游戏状态的依赖,所有圆形按钮都使用相同的逻辑绘制它们自己,也就是说,当游戏完成时,它们都将被绘制为白色

相反,您应该依赖按钮的属性。对其进行设置,使颜色实际上源自按钮本身

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class BadButton01 {

    public static void main(String[] args) {
        new BadButton01();
    }

    public BadButton01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public static class GameState {

        private static boolean isComplete;

        public static boolean getIfComplete() {
            return isComplete;
        }

        public static void setComplete(boolean value) {
            isComplete = value;
        }

    }

    public class TestPane extends JPanel {

        private RoundButton[] btns = new RoundButton[]
        {
            new RoundButton("1"),
            new RoundButton("2"),
            new RoundButton("3"),
            new RoundButton("4"),
            new RoundButton("5"),
            new RoundButton("6"),
            new RoundButton("7"),
            new RoundButton("8"),
            new RoundButton("9")
        };

        public TestPane() {
            setLayout(new GridLayout(3, 3));
            for (RoundButton btn : btns) {
                add(btn);
            }
            btns[0].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    GameState.setComplete(true);
                    btns[0].setBackground(Color.WHITE);
                    btns[1].setBackground(Color.WHITE);
                    btns[2].setBackground(Color.WHITE);
                    repaint();
                }
            });
        }

    }

    public class RoundButton extends JButton {

        public RoundButton(String label) {
            super(label);
            this.setContentAreaFilled(false);
            setBorderPainted(false);
            setFocusPainted(false);
            setOpaque(false);
            Dimension size = this.getPreferredSize();
            size.height = size.width = Math.max(size.height, size.width);
            this.setPreferredSize(size);
            setBackground(Color.GREEN);
        }

        @Override
        protected void paintComponent(Graphics g) {
//            if (!GameState.getIfComplete()) { // If the game is not complete or has just started
//                this.setBorder(null);
//                g.setColor(Color.BLACK);
//                g.fillRect(0, 0, this.getSize().width, this.getSize().height);
                if (this.getModel().isArmed()) {
                    g.setColor(Color.RED);
                } else {
//                    g.setColor(Color.GREEN);
                    g.setColor(getBackground());
                }
//            } else {
//                this.setBorder(null);
//                g.setColor(Color.BLACK);
//                g.fillRect(0, 0, this.getSize().width, this.getSize().height);
//                g.setColor(Color.WHITE);
//                g.fillOval(0, 0, this.getSize().width - 1, this.getSize().height - 1);
//                g.setColor(getBackground());
//            }
            g.fillOval(0, 0, this.getSize().width - 1, this.getSize().height - 1);
            super.paintComponent(g);
        }

    }

}

问题在于对游戏状态的依赖,所有圆形按钮都使用相同的逻辑来绘制它们自己,也就是说,当游戏完成时,它们都将被绘制为白色

相反,您应该依赖按钮的属性。对其进行设置,使颜色实际上源自按钮本身

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class BadButton01 {

    public static void main(String[] args) {
        new BadButton01();
    }

    public BadButton01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public static class GameState {

        private static boolean isComplete;

        public static boolean getIfComplete() {
            return isComplete;
        }

        public static void setComplete(boolean value) {
            isComplete = value;
        }

    }

    public class TestPane extends JPanel {

        private RoundButton[] btns = new RoundButton[]
        {
            new RoundButton("1"),
            new RoundButton("2"),
            new RoundButton("3"),
            new RoundButton("4"),
            new RoundButton("5"),
            new RoundButton("6"),
            new RoundButton("7"),
            new RoundButton("8"),
            new RoundButton("9")
        };

        public TestPane() {
            setLayout(new GridLayout(3, 3));
            for (RoundButton btn : btns) {
                add(btn);
            }
            btns[0].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    GameState.setComplete(true);
                    btns[0].setBackground(Color.WHITE);
                    btns[1].setBackground(Color.WHITE);
                    btns[2].setBackground(Color.WHITE);
                    repaint();
                }
            });
        }

    }

    public class RoundButton extends JButton {

        public RoundButton(String label) {
            super(label);
            this.setContentAreaFilled(false);
            setBorderPainted(false);
            setFocusPainted(false);
            setOpaque(false);
            Dimension size = this.getPreferredSize();
            size.height = size.width = Math.max(size.height, size.width);
            this.setPreferredSize(size);
            setBackground(Color.GREEN);
        }

        @Override
        protected void paintComponent(Graphics g) {
//            if (!GameState.getIfComplete()) { // If the game is not complete or has just started
//                this.setBorder(null);
//                g.setColor(Color.BLACK);
//                g.fillRect(0, 0, this.getSize().width, this.getSize().height);
                if (this.getModel().isArmed()) {
                    g.setColor(Color.RED);
                } else {
//                    g.setColor(Color.GREEN);
                    g.setColor(getBackground());
                }
//            } else {
//                this.setBorder(null);
//                g.setColor(Color.BLACK);
//                g.fillRect(0, 0, this.getSize().width, this.getSize().height);
//                g.setColor(Color.WHITE);
//                g.fillOval(0, 0, this.getSize().width - 1, this.getSize().height - 1);
//                g.setColor(getBackground());
//            }
            g.fillOval(0, 0, this.getSize().width - 1, this.getSize().height - 1);
            super.paintComponent(g);
        }

    }

}

您可能只需要创建彩色图标并将其设置为标准按钮。为了更快地获得更好的帮助,请发布一个。我相信我已经通过调用this.setboordnull解决了这个问题;这是一个可怕的坏主意。如果不希望设置边框,请尝试重写getBorder方法并从返回nullit@MadProgrammer是 啊我也解决了这个问题。这在这里得到了反映。@saplingPro没问题,我还添加了一些额外的想法;您可能只需要创建彩色图标并将其设置为标准按钮。为了更快地获得更好的帮助,请发布一个。我相信我已经通过调用this.setboordnull解决了这个问题;这是一个可怕的坏主意。如果不希望设置边框,请尝试重写getBorder方法并从返回nullit@MadProgrammer是 啊我也解决了这个问题。这在这里得到了反映。@saplingPro没问题,我还添加了一些额外的想法;为什么调用按钮[btn_number]不显示呢?重新绘制不会只绘制特定的按钮,因为这不是绘制的方式。重绘管理器接受所有重绘请求,并可以将它们组合成单个请求,其中可能包括其他组件。克服你控制绘画过程的错觉,你不控制,重新绘画!是的。查看更深入的解释,以及为什么呼叫按钮[btn_number]没有。重新绘制不会只绘制特定的按钮,因为这不是绘制的方式。重绘管理器接受所有重绘请求,并可以将它们组合成单个请求,其中可能包括其他组件。克服你控制绘画过程的错觉,你不控制,重新绘画!是的。查看更不深入的解释