为什么重绘()不起作用?

时间:2015-04-24 03:34:52

标签: java swing

我正在尝试将按钮添加到我创建的centerPanel,然后将该面板添加到主中心borderlayout。由于某种原因,虽然我的标签不再重新绘制。前一段时间我在与MagicSquare相同的类文件中使用DrawFieldsListener类时效果很好,但代码中的任何内容都没有从我将它们分成两个类文件而改变。所以我真的不知道发生了什么。如果它之前重绘过,那也需要很长时间。有帮助吗?谢谢!

项目的所有来源都在GitHub上,如果它更易于阅读和理解:https://github.com/andrefecto/Academic-Convivium-Project

MagicSquare类:

package magicSquare;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class MagicSquare extends JPanel {
    JLabel sizeLabel = new JLabel("Enter A Square Size: ");
    JButton setSize;
    static JButton calculate;
    static JButton reset;
    static JTextField squareSize;
    static JTextField field;

    public static ArrayList<JTextField> inputFields = new ArrayList<JTextField>();
    public static ArrayList<Integer> inputs = new ArrayList<Integer>();
    public static ArrayList<Integer> totals = new ArrayList<Integer>();

    public static int squared = 0;
    public static int square = 0;

    public static JPanel centerPanel = new JPanel();
    public static JPanel bottomPanel = new JPanel();

    public MagicSquare (){
        setLayout(new BorderLayout());
        JPanel subPanel = new JPanel();

        subPanel.add(sizeLabel);

        squareSize = new JTextField();
        squareSize.setColumns(6);
        subPanel.add(squareSize);

        setSize = new JButton("Enter");
        subPanel.add(setSize);
        setSize.addActionListener(new DrawFieldsListener());

        add(subPanel, BorderLayout.NORTH);
        add(new DrawFieldsListener(), BorderLayout.CENTER);
    }
}

我的DrawFieldsListener类:

package magicSquare;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;

class DrawFieldsListener extends JPanel implements ActionListener {

    int square = MagicSquare.square;
    int squared = MagicSquare.squared;
    JPanel centerPanel = MagicSquare.centerPanel;
    JTextField squareSize = MagicSquare.squareSize;
    JTextField field = MagicSquare.field;
    ArrayList<JTextField> inputFields = MagicSquare.inputFields;
    JButton calculate = MagicSquare.calculate;
    JButton reset = MagicSquare.reset;
    JPanel bottomPanel = MagicSquare.bottomPanel;

    public void actionPerformed(ActionEvent e){
        square = Integer.parseInt(squareSize.getText());
        squared = square*square;

        centerPanel.setLayout(new GridLayout(square, square));

        for(int i = 0; i < squared; i++){
            field = new JTextField();
            field.setColumns(3);
            inputFields.add(field);
            centerPanel.add(inputFields.get(i));
            System.out.println("DRAWING");
        }

        add(centerPanel, BorderLayout.CENTER);
        System.out.println("ADDING ADDITINOAL BUTTONS");
        additionalButtons();
        System.out.println("ADDED ADDITINOAL BUTTONS");
        System.out.println("REPAINTING");
        repaint();
        System.out.println("REPAINTED");
    }
    public void additionalButtons(){
        calculate = new JButton("Calculate");
        reset = new JButton("Reset");

        bottomPanel.setLayout(new GridLayout(2, 2));
        bottomPanel.add(reset);
        bottomPanel.add(calculate);

        add(bottomPanel, BorderLayout.SOUTH);

        calculate.addActionListener(new CalculateListener());
        reset.addActionListener(new ResetListener());
    }
}

1 个答案:

答案 0 :(得分:3)

错误#1

public static JPanel centerPanel = new JPanel();

接下来......

class DrawFieldsListener extends JPanel implements ActionListener {
    //...
    JPanel centerPanel = MagicSquare.centerPanel;

static不是跨对象通信机制......现在我不知道谁应该负责管理centerPanel ...

请记住,static不是你的朋友,请注意它的使用方式

错误#2

setSize.addActionListener(new DrawFieldsListener());

add(subPanel, BorderLayout.NORTH);
add(new DrawFieldsListener(), BorderLayout.CENTER);

您正在创建DrawFieldsListener的两个实例(这是一个面板),一个充当ActionListener,一个充当视图,但实际上是MagicSquare.centerPanel作为一个组件只能有一个父...

错误#3

更改容器后不重新验证容器......

    public void actionPerformed(ActionEvent e) {
        square = Integer.parseInt(squareSize.getText());
        squared = square * square;

        centerPanel.setLayout(new GridLayout(square, square));

        for (int i = 0; i < squared; i++) {
            field = new JTextField();
            field.setColumns(3);
            inputFields.add(field);
            centerPanel.add(inputFields.get(i));
            System.out.println("DRAWING");
        }

        add(centerPanel, BorderLayout.CENTER);
        System.out.println("ADDING ADDITINOAL BUTTONS");
        additionalButtons();
        System.out.println("ADDED ADDITINOAL BUTTONS");
        System.out.println("REPAINTING");
        revalidate();
        repaint();
        System.out.println("REPAINTED");
    }

Swing在容器管理方面很懒惰,它假设您需要进行多次添加或删除,因此在您要求之前不会更新容器层次结构布局,因为操作可能很昂贵

更好的解决方案......

隔离责任并以解耦方式向对象提供信息。

例如,DrawFieldsListener不应该关心MagicSquare,而应该提供一种方法,通过这种方法,“某个身体”可以告诉它应该创建多少个方格。

Squares

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MagicSquare extends JPanel {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new MagicSquare());
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    JLabel sizeLabel = new JLabel("Enter A Square Size: ");
    JButton setSize;
    private JSpinner squareSize;
    JTextField field;

    public MagicSquare() {
        setLayout(new BorderLayout());
        JPanel subPanel = new JPanel();

        subPanel.add(sizeLabel);

        squareSize = new JSpinner();
        subPanel.add(squareSize);

        setSize = new JButton("Enter");
        subPanel.add(setSize);
        DrawFieldsListener dfl = new DrawFieldsListener();
        setSize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int gridSize = (int) squareSize.getValue();
                dfl.makeGrid(gridSize);
            }
        });

        add(subPanel, BorderLayout.NORTH);
        add(dfl, BorderLayout.CENTER);
    }

    class DrawFieldsListener extends JPanel {

        private JButton calculate;
        private JButton reset;

        private ArrayList<JTextField> inputFields = new ArrayList<JTextField>();
        private ArrayList<Integer> inputs = new ArrayList<Integer>();
        private ArrayList<Integer> totals = new ArrayList<Integer>();

        private int squared = 0;
        private int square = 0;

        private JPanel centerPanel = new JPanel();
        private JPanel bottomPanel = new JPanel();

        public void makeGrid(int gridSize) {
            square = gridSize;
            squared = square * square;

            centerPanel.setLayout(new GridLayout(square, square));

            for (int i = 0; i < squared; i++) {
                field = new JTextField();
                field.setColumns(3);
                inputFields.add(field);
                centerPanel.add(inputFields.get(i));
                System.out.println("DRAWING");
            }

            add(centerPanel, BorderLayout.CENTER);
            System.out.println("ADDING ADDITINOAL BUTTONS");
            additionalButtons();
            System.out.println("ADDED ADDITINOAL BUTTONS");
            System.out.println("REPAINTING");
            revalidate();
            repaint();
            System.out.println("REPAINTED");
        }

        public void additionalButtons() {
            calculate = new JButton("Calculate");
            reset = new JButton("Reset");

            bottomPanel.setLayout(new GridLayout(2, 2));
            bottomPanel.add(reset);
            bottomPanel.add(calculate);

            add(bottomPanel, BorderLayout.SOUTH);

//          calculate.addActionListener(new CalculateListener());
//          reset.addActionListener(new ResetListener());
        }
    }
}