【问题标题】:Java GUI repainting error?Java GUI重绘错误?
【发布时间】:2010-09-27 14:51:53
【问题描述】:

这是一个艰难的 - 我有一个生成 JTextFields 的 JFrame。当我从生成 2 个 JTextField 到 12 个 JTextfield(例如)时,我看到一些错误,其中最后有一个不同大小的 JTextField。好像是重绘错误。

Main.java 代码:

import java.awt.*;
import javax.swing.*;

public class Main {
    public static Display display = new Display();

    public static void main(String[] args) {
        display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        display.setVisible(true);
    }
}

Display.java 代码:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Display extends JFrame {
    final int FRAME_WIDTH = 820;
    final int FRAME_HEIGHT = 700;
    final int X_OFFSET = 40;
    final int Y_OFFSET = 40;

    final int GRAPH_OFFSETX = 35;
    final int GRAPH_OFFSETY = 60;
    final int GRAPH_WIDTH = 500;
    final int GRAPH_HEIGHT = 500;
    final int GRAPH_INTERVAL = 20;

    JButton submit;
    JTextField top;
    JTextField bottom;
    JTextField numPoint;
    JPanel bpanel;
    JPanel points;

    int maxPoints;

    public Display() {
        init();
    }

    public void init() {
        setBackground(Color.WHITE);
        setLocation(X_OFFSET, Y_OFFSET);
        setSize(FRAME_WIDTH, FRAME_HEIGHT);
        setTitle("Geometric Transformations");
        getContentPane().setLayout(null);
        setDefaultLookAndFeelDecorated(true);

        top = new JTextField();    // parameter is size of input characters
        top.setText("1 2 3");
        top.setBounds(590, 150, 120, 25);

        bottom = new JTextField();    // parameter is size of input characters
        bottom.setText("5 6 7");
        bottom.setBounds(590, 200, 120, 25);

        numPoint = new JTextField();
        numPoint.setText("Number of Points?");
        numPoint.setBounds(550,200,200,25);
        this.add(numPoint);

        SubmitButton submit = new SubmitButton("Submit");
        submit.setBounds(570, 250, 170, 25);

        bpanel = new JPanel(new GridLayout(2,3));
        bpanel.add(top);
        bpanel.add(bottom);
        bpanel.add(submit);

        points = new JPanel(new GridLayout(2,2));
        points.setBounds(540,250,265,60);
        this.add(points);

        bpanel.setBounds(550,100,200,70);
        this.add(bpanel, BorderLayout.LINE_START);

        Component[] a = points.getComponents();
        System.out.println(a.length);
        repaint();
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.WHITE);
        g.fillRect(100, 100, 20, 30);
        g.setColor(Color.BLACK);
        genGraph(g, GRAPH_OFFSETX, GRAPH_OFFSETY, GRAPH_WIDTH, GRAPH_HEIGHT, GRAPH_INTERVAL);
    }

    public void genGraph (Graphics g, int x, int y, int width, int height, int interval) {
        // draw background
        int border = 5;
        g.setColor(Color.BLACK);
        width = width - (width % interval);
        height = height - (height % interval);
        for (int col=x; col <= x+width; col+=interval) {
            g.drawLine(col, y, col, y+height);
        }
        for (int row=y; row <= y+height; row+=interval) {
            g.drawLine(x, row, x+width, row);
        }
    }
    class SubmitButton extends JButton implements ActionListener {

        public SubmitButton(String title){
            super(title);
            addActionListener(this);
            this.setVisible(true);
        }
        public void actionPerformed(ActionEvent e) {
            maxPoints = Integer.parseInt(numPoint.getText()) * 2;

            points.removeAll();

            for (int i=0; i<maxPoints; i++) {
                JTextField textField = new JTextField();
                points.add(textField);
            }
            points.validate();        // necessary when adding components to a JPanel
            // http://stackoverflow.com/questions/369823/java-gui-repaint-problem-solved
            // What to Check:
            // Things between commas are either spaces (which will be stripped later)
            // or numbers!

            // Pairs must match up!
        }
    }
}

【问题讨论】:

  • 当我在“点数”字段中输入“2”并按下提交,然后将其更改为“12”并按下提交时似乎没有任何问题(没有额外不同大小的 JTextField)......您可以通过屏幕截图来扩展您的错误吗?
  • 我标记的答案解决了问题,但基本上当我从输入 2 到 12 之类的内容时,会绘制 12 个文本字段,除了右侧有一个直接绘制的文本字段(不可点击)。仅在 windows/mac 中存在问题(我忘记了哪一个 >

标签: java user-interface jframe repaint


【解决方案1】:

新组件在以前的组件上重新绘制。 我在points.validate(); 之后添加了points.repaint();,问题就消失了。

【讨论】:

    【解决方案2】:

    注意:我也对重新绘制网格的问题感到恼火(将窗口放在前面然后放在后面,你会看到)。
    从快速搜索来看,最好避免直接在 JFrame 上进行绘制,而是将其委托给子组件。如果我错了,有人告诉我。 这是我的解决方案(不完美,我留给你改进它的任务...... :-P

    import java.awt.*;
    import java.awt.event.*;
    
    import javax.swing.*;
    
    public class SODisplay extends JFrame {
        final int FRAME_WIDTH = 820;
        final int FRAME_HEIGHT = 700;
        final int X_OFFSET = 40;
        final int Y_OFFSET = 40;
    
        JButton submit;
        JTextField top;
        JTextField bottom;
        JTextField numPoint;
        JPanel bpanel;
        JPanel points;
        GridPanel grid;
    
        int maxPoints;
    
        public SODisplay() {
            init();
        }
    
        public void init() {
            setBackground(Color.WHITE);
            setLocation(X_OFFSET, Y_OFFSET);
            setSize(FRAME_WIDTH, FRAME_HEIGHT);
            setTitle("Geometric Transformations");
            getContentPane().setLayout(null);
            setDefaultLookAndFeelDecorated(true);
    
            grid = new GridPanel();
            grid.setBounds(0,0,530,FRAME_HEIGHT);
            this.add(grid);
    
            top = new JTextField();    // parameter is size of input characters
            top.setText("1 2 3");
            top.setBounds(590, 150, 120, 25);
    
            bottom = new JTextField();    // parameter is size of input characters
            bottom.setText("5 6 7");
            bottom.setBounds(590, 200, 120, 25);
    
            numPoint = new JTextField();
            numPoint.setText("Number of Points?");
            numPoint.setBounds(550,200,200,25);
            this.add(numPoint);
    
            SubmitButton submit = new SubmitButton("Submit");
            submit.setBounds(570, 250, 170, 25);
    
            bpanel = new JPanel(new GridLayout(2,3));
            bpanel.add(top);
            bpanel.add(bottom);
            bpanel.add(submit);
    
            points = new JPanel(new GridLayout(2,2));
            points.setBounds(540,250,265,60);
            this.add(points);
    
            bpanel.setBounds(550,100,200,70);
            this.add(bpanel, BorderLayout.LINE_START);
    
            Component[] a = points.getComponents();
            System.out.println(a.length);
            repaint();
        }
    
        class SubmitButton extends JButton implements ActionListener {
    
            public SubmitButton(String title){
                super(title);
                addActionListener(this);
                this.setVisible(true);
            }
            public void actionPerformed(ActionEvent e) {
                maxPoints = Integer.parseInt(numPoint.getText()) * 2;
    
                points.removeAll();
    
                for (int i=0; i<maxPoints; i++) {
                    JTextField textField = new JTextField();
                    points.add(textField);
                }
                points.validate();        // necessary when adding components to a JPanel
                points.repaint();
                // http://stackoverflow.com/questions/369823/java-gui-repaint-problem-solved
                // What to Check:
                // Things between commas are either spaces (which will be stripped later)
                // or numbers!
    
                // Pairs must match up!
            }
        }
    
        public static void main(String[] args) {
            // Schedule a job for the event-dispatching thread:
            // creating and showing this application's GUI.
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    SODisplay display = new SODisplay();
                    display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    display.setVisible(true);
                }
            });
        }
    
        class GridPanel extends JPanel {
            // Or drop the offset and adjust the placement of the component
            final int GRAPH_OFFSETX = 35;
            final int GRAPH_OFFSETY = 60;
            final int GRAPH_WIDTH = 500;
            final int GRAPH_HEIGHT = 500;
            final int GRAPH_INTERVAL = 20;
    
            public GridPanel() {
            }
    
            public void paint(Graphics g) {
                super.paint(g);
                g.setColor(Color.WHITE);
                g.fillRect(100, 100, 20, 30);
                g.setColor(Color.BLACK);
                genGraph(g, GRAPH_OFFSETX, GRAPH_OFFSETY, GRAPH_WIDTH, GRAPH_HEIGHT, GRAPH_INTERVAL);
            }
    
            public void genGraph (Graphics g, int x, int y, int width, int height, int interval) {
                // draw background
                int border = 5;
                g.setColor(Color.BLACK);
                width = width - (width % interval);
                height = height - (height % interval);
                for (int col=x; col <= x+width; col+=interval) {
                    g.drawLine(col, y, col, y+height);
                }
                for (int row=y; row <= y+height; row+=interval) {
                    g.drawLine(x, row, x+width, row);
                }
            }
        }
    }
    

    为了简单起见,这只是我在一个文件中的测试代码,当然,您可能希望以不同的方式剖析它。

    【讨论】:

      猜你喜欢
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多