views:

50

answers:

1

I've written an application in Swing that listens for UDP packets from a smart battery and displays them in JTextFields inside a JPanel inside a JFrame.

For some reason, minimizing the application and then restoring it smooshes all the text inside the center of the main frame and prevents updates to the JTextFields to be drawn to the screen.

I'm not sure why this is happening (Swing newb) or exactly how to fix it. Below are code snippets with the relevant code.

public class Initializer {

public void initialize() {

            //The mediator performs all updates of the BatteryPanel
            mediator = Mediator.getInstance();

            //BatteryService listens for UDP packets and uses mediator to update panel
            bService = new BatteryService();

    createGUI();

    bService.start();   
}

public void createGUI() {

    bPanel = new BatteryPanel();
    frame = new JFrame();

            //For spacing between the BatteryPanel and the edge of the window
    frame.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.insets = new Insets(6,8,8,6);

    frame.getContentPane().add(bPanel, gbc);
    frame.setResizable(false);

    mediator.setBatteryPanel(bPanel);
    frame.pack();
    frame.setVisible(true);

}
} 

public class BatteryService {
   private Mediator mediator;
   ...
         //This is inside a SwingWorker - we have data now update the panel
         protected void process(List<BatteryUpdateBean> bBeans) {
           ...
           mediator.setBatteryStatus(status);
           mediator.setTemperature(temperature);
           mediator.setLastConnected(lastConnected);
         }
       }
   }
}

public class BatteryPanel extends JPanel {

private static final int AFTER_LABEL_SPACE = 8;
private static final int AFTER_TITLE_SPACE = 8;
private static final int BETWEEN_ROWS_SPACE = 3;

private JTextField statusField;
private JTextField temperatureField;
private JTextField lastConnectedField;

public BatteryPanel() {     
    initComponents();
}

    //get textfield methods snipped
    ...

private void initComponents() {
    JLabel titleLabel = new JLabel("Battery");
    titleLabel.setFont(new Font("Tahoma", Font.BOLD, 14));

    JLabel lastConnectedLabel = new JLabel("Last connected:");
    JLabel statusLabel = new JLabel("Status:");
    JLabel temperatureLabel = new JLabel("Temperature:");

    temperatureField= new JTextField("NO CONNECTION                ");
    temperatureField.setOpaque(false);
    temperatureField.setEditable(false);
    temperatureField.setBorder(BorderFactory.createEmptyBorder());

    statusField= new JTextField("                                 ");
    statusField.setOpaque(false);
    statusField.setEditable(false);
    statusField.setBorder(BorderFactory.createEmptyBorder());

    powerField = new JTextField("                             ");
    powerField.setOpaque(false);
    powerField.setEditable(false);
    powerField.setBorder(BorderFactory.createEmptyBorder());


    setLayout(new GridBagLayout());

    GridBagConstraints titleC = new GridBagConstraints();
    GridBagConstraints lastConnectedLabelC = new GridBagConstraints();
    GridBagConstraints statusLabelC = new GridBagConstraints();
    GridBagConstraints temperatureLabelC = new GridBagConstraints();
    GridBagConstraints statusFieldC = new GridBagConstraints();
    GridBagConstraints temperatureFieldC = new GridBagConstraints();
    GridBagConstraints lastConnectedFieldC = new GridBagConstraints();

    titleC.gridx = 0; titleC.gridy = 0; titleC.gridwidth = 2;
    titleC.anchor = GridBagConstraints.FIRST_LINE_START;
    titleC.insets = new Insets(0, 0, AFTER_TITLE_SPACE, 0);

    lastConnectedLabelC.gridx = 0;  lastConnectedLabelC.gridy = 1;
    lastConnectedLabelC.anchor = GridBagConstraints.LINE_START;
    lastConnectedLabelC.insets = new Insets(0,0,BETWEEN_ROWS_SPACE,AFTER_LABEL_SPACE);

    lastConnectedFieldC.gridx = 1; lastConnectedFieldC.gridy = 1;
    lastConnectedFieldC.anchor = GridBagConstraints.LINE_START;
    lastConnectedFieldC.insets = new Insets(0,0,BETWEEN_ROWS_SPACE,0);

    statusLabelC.gridx = 0; statusLabelC.gridy = 2;
    statusLabelC.anchor = GridBagConstraints.LINE_START;
    statusLabelC.insets = new Insets(0,0,BETWEEN_ROWS_SPACE,AFTER_LABEL_SPACE);

    statusFieldC.gridx = 1; statusFieldC.gridy = 2;
    statusFieldC.anchor = GridBagConstraints.LINE_START;
    statusFieldC.insets = new Insets(0,0,BETWEEN_ROWS_SPACE,0);
    statusFieldC.fill = GridBagConstraints.HORIZONTAL;

    temperatureLabelC.gridx = 0; temperatureLabelC.gridy = 3;
    temperatureLabelC.anchor = GridBagConstraints.LINE_START;
    temperatureLabelC.insets = new Insets(0,0,BETWEEN_ROWS_SPACE,AFTER_LABEL_SPACE);


    temperatureFieldC.gridx = 1; temperatureFieldC.gridy = 3;
    temperatureFieldC.anchor = GridBagConstraints.LINE_START;
    temperatureFieldC.insets = new Insets(0,0,BETWEEN_ROWS_SPACE,0);

    ...
            //add (item, constraints) snipped       
}

I'd greatly appreciate anyone's help with this.

+2  A: 

On your GridBagConstraints at the top level, have you considered setting the other properties of the object? I'd look into:

gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;

Also, in your BatteryPanel, you can re-use the same GridBagConstraints object and just change the values. Check out the GridBagLayout tutorial for more information.

Once you fix your layout, I think you'll find the behavior to be as expected.

justkt
You also need at least one component that has a weightx and weighty value in its GridBagConstraints otherwise all components will be clustered in the middle of the container
willcodejavaforfood
Good catch, thanks. Added.
justkt
Great - that does it. I added those lines to the top GridBagConstraints, and also added: weightx = .5 fill = GridBagConstraints.HORIZONTALto each of the changing JTextFields.
cuttcards