JSpinner无法正确显示

时间:2017-07-24 22:18:34

标签: java swing

过去一个月我一直在研究GUI,我发现JSpinner不知何故停止正确显示。只有边框出现,没有数字,没有箭头,看图片:

enter image description here

我可以判断某个组件何时启用,但这不是问题。

起始类,MAIN方法为:

import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JPopupMenu;

public class Starter extends JFrame {

    public final int WIDTH = 205, HEIGHT = 280;

    private static final long serialVersionUID = 1L;

    public Starter() throws InterruptedException {
        super("Editor");
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        setLocation(0, 0);
        setSize(WIDTH + 5, HEIGHT + 50);
        setVisible(true);
        setResizable(false);
        setLocation(80, 180);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);

        loadCaterogy(new EditorObjectProperties());
    }

    public void loadCaterogy(EditorCategoryTemplate category) {
        for (Component component : category.getCategoryComponents()) {
            add(component);
        }
        repaint();
    }

    public static void main(String[] args) {
        try {
            new Starter();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

编辑类别 - 所有组件均为:

import java.awt.Font;
import java.awt.TextArea;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

public class EditorObjectProperties extends EditorCategoryTemplate {

    public JLabel xLabel;
    public JSpinner xSpinner;
    public JLabel yLabel;
    public JSpinner ySpinner;
    public JLabel angleLabel;
    public JSpinner angleSpinner;
    public JLabel widthLabel;
    public JSpinner widthSpinner;
    public JButton deleteButton;

    public JLabel textLabel;
    public TextArea textArea;

    public void addCategoryComponents() {
        xLabel = new JLabel("x:");
        xLabel.setFont(new Font("Tahoma", Font.PLAIN, 14));
        xLabel.setBounds(25, 15, 15, 14);
        add(xLabel);

        xSpinner = new JSpinner(new SpinnerNumberModel(0, 0, WIDTH, 1));
        xSpinner.setBounds(42, 12, 50, 20);
        xSpinner.setEnabled(false);
        add(xSpinner);

        yLabel = new JLabel("y:");
        yLabel.setFont(new Font("Tahoma", Font.PLAIN, 14));
        yLabel.setBounds(102, 12, 15, 20);
        add(yLabel);

        ySpinner = new JSpinner(new SpinnerNumberModel(0, 0, HEIGHT, 1));
        ySpinner.setBounds(117, 12, 50, 20);
        ySpinner.setEnabled(false);
        add(ySpinner);

        angleLabel = new JLabel("angle:");
        angleLabel.setFont(new Font("Tahoma", Font.PLAIN, 14));
        angleLabel.setBounds(25, 47, 50, 20);
        add(angleLabel);

        angleSpinner = new JSpinner(new SpinnerNumberModel(0, -5, 360, 5));
        angleSpinner.setBounds(72, 49, 95, 20);
        angleSpinner.setEnabled(false);
        add(angleSpinner);

        widthLabel = new JLabel("width:");
        widthLabel.setFont(new Font("Tahoma", Font.PLAIN, 14));
        widthLabel.setBounds(25, 87, 50, 20);
        add(widthLabel);

        widthSpinner = new JSpinner(new SpinnerNumberModel(10, 10, WIDTH, 10));
        widthSpinner.setBounds(72, 86, 95, 20);
        widthSpinner.setEnabled(false);
        add(widthSpinner);

        textLabel = new JLabel("text:");
        textLabel.setFont(new Font("Tahoma", Font.PLAIN, 14));
        textLabel.setBounds(25, 173, 50, 20);
        add(textLabel);

        textArea = new TextArea();
        textArea.setBounds(72, 127, 95, 112);
        textArea.setEnabled(false);
        add(textArea);

        deleteButton = new JButton("Delete Object");
        deleteButton.setBounds(10, 250, 174, 25);
        deleteButton.setEnabled(false);
        add(deleteButton);
        add(new JLabel());
    }
}

抽象类别模板,其中一些幕后方法是:

import java.awt.Component;
import java.util.ArrayList;

public abstract class EditorCategoryTemplate {

    public final int WIDTH = 205, HEIGHT = 280;

    public ArrayList<Component> components;

    public EditorCategoryTemplate() {
        this.components = new ArrayList<Component>();
        start();
    }

    public abstract void addCategoryComponents();

    public void add(Component component) {
        components.add(component);
    }

    public ArrayList<Component> getCategoryComponents() {
        return components;
    }

    private void start() {
        addCategoryComponents();
    }
}

1 个答案:

答案 0 :(得分:2)

您的问题与Swing线程无关,与布局无关,也没有正确使用它们,实际上您有三个主要问题:

  1. 您正在尝试将组件添加到容器,这里是JFrame的contentPane,就好像容器使用了null布局,但实际上它没有,而是使用BorderLayout作为其默认布局。
  2. 在将组件添加到GUI之前,您过早地在JFrame上调用setVisible(true)
  3. 只是你使用绝对定位的事实是一个主要问题。如果您希望在所有平台上正确定位和调整组件,Swing GUI需要正确使用布局管理器。
  4. 请注意,这并不是说您的线程是正确的,事实并非如此,但修复此问题绝不会修复因此而导致的GUI和布局问题。

    因此,对于“快速修复”,您可以通过以下方式解决问题1和2:

    public Starter() throws InterruptedException {
        super("Editor");
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        setLocation(0, 0);
        setSize(WIDTH + 5, HEIGHT + 50);
    
        // **** REMOVE ****
        // setVisible(true); 
    
        setResizable(false);
        setLocation(80, 180);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
    
        // **** ADD ****
        getContentPane().setLayout(null);   
    
        loadCaterogy(new EditorObjectProperties());
    
        // **** ADD ****
        setVisible(true);  
    }
    

    对于更强大的修复,我会更多地使用布局管理器。例如,这可能是一个起点:

    import java.awt.BorderLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    
    import javax.swing.*;
    
    public class EditorEg extends JPanel {
        private static final int MAX_X = 205;
        private static final int MAX_Y = 280;
        private static final int TA_ROWS = 8;
        private static final int TA_COLS = 16;
        private JSpinner xSpinner = new JSpinner(new SpinnerNumberModel(0, 0, MAX_X, 1));
        private JSpinner ySpinner = new JSpinner(new SpinnerNumberModel(0, 0, MAX_Y, 1));
        private JSpinner angleSpinner = new JSpinner(new SpinnerNumberModel(0, -5, 360, 5));
        private JSpinner widthSpinner = new JSpinner(new SpinnerNumberModel(10, 10, MAX_X, 10));
        private JTextArea textArea = new JTextArea(TA_ROWS, TA_COLS);
        private JButton deleteButton = new JButton("Delete");
    
        public EditorEg() {
            JPanel xyPanel = new JPanel(new GridBagLayout());
            int gap = 2;
            Insets insets = new Insets(gap, gap, gap, gap);
            GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
                    GridBagConstraints.BASELINE, GridBagConstraints.HORIZONTAL, insets, 0, 0);
            gbc.weightx = 0.2;
            xyPanel.add(new JLabel("x:"), gbc);
            gbc.gridx++;
            gbc.weightx = 1.0;
            xyPanel.add(xSpinner, gbc);
            gbc.gridx++;
            gbc.weightx = 0.2;
            xyPanel.add(new JLabel("y:"), gbc);
            gbc.gridx++;
            gbc.weightx = 1.0;
            xyPanel.add(ySpinner, gbc);
    
            JPanel angleWidthPanel = new JPanel(new GridBagLayout());
            gap = 3;
            insets = new Insets(gap, gap, gap, gap);
            gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
                    GridBagConstraints.BASELINE, GridBagConstraints.HORIZONTAL, insets, 0, 0);
            angleWidthPanel.add(new JLabel("angle:"), gbc);
            gbc.gridx++;
            angleWidthPanel.add(angleSpinner, gbc);
            gbc.gridx--;
            gbc.gridy++;
            angleWidthPanel.add(new JLabel("width:"), gbc);
            gbc.gridx++;
            angleWidthPanel.add(widthSpinner, gbc);
    
            JScrollPane scrollPane = new JScrollPane(textArea);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    
            JPanel scrollWrapper = new JPanel(new BorderLayout());
            scrollWrapper.setBorder(BorderFactory.createTitledBorder("Text"));
            scrollWrapper.add(scrollPane);
    
            setLayout(new GridBagLayout());
            gap = 4;
            setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
            insets = new Insets(gap, gap, gap, gap);
    
            gbc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
                    GridBagConstraints.BASELINE, GridBagConstraints.HORIZONTAL, insets, 0, 0);
            add(xyPanel, gbc);
            gbc.gridy++;
            add(angleWidthPanel, gbc);
            gbc.gridy++;
            add(scrollWrapper, gbc);
            gbc.gridy++;
            add(deleteButton, gbc);
        }
    
        private static void createAndShowGui() {
            EditorEg mainPanel = new EditorEg();
    
            JFrame frame = new JFrame("Editor");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    }