Bill Willian Bill Willian - 3 years ago 73
Java Question

JSpinner not displaying correctly

I have been working on a GUI for the past month and I found that somehow the JSpinner stopped being displayed correctly. Only the border is appearing, no number, no arrows, look at the picture:

enter image description here

I can tell when a component is enabled or not but that is not the problem.

The starter class, where the MAIN method is:

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


The Editor Category - Where all the components are:

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


And the Abstract Category Template, where some behind the scenes methods are:

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

Answer Source

Your problem has nothing to do with Swing threading and all to do with layouts and not using them correctly, and in fact you have three major problems:

  1. You're trying to add components to a container, here a JFrame's contentPane, as if the container used a null layout, but when in fact it doesn't and instead uses a BorderLayout as its default layout.
  2. You're calling setVisible(true) on your JFrame too early, before components have been added to the GUI
  3. Just the fact that you're using absolute positioning at all is a major problem. Swing GUI's need the proper use of layout managers if you desire components to be positioned and sized correctly on all platforms.

Note that this is not to say that your threading is correct, it isn't, but fixing this will in no way fix your GUI and layout problems which cannot be caused by this.

So for a "quick fix" you could fix problems 1 and 2 via:

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

For a more robust fix, I'd play with layout managers a bit more. For example, this could be a starting point:

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());
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download