views:

78

answers:

3

I am a newbie at Java Swing/AWT and I have this code following working for a simple PopUp dialog which closes on any of the JButtons beind clicked, but displays real wonky. Does anybody have suggestions on what and how to fix?

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Box.Filler;


public class UpgradePopupWindow extends JPanel implements ActionListener {
//public static UpgradePopupWindow mainWindow;

static final long serialVersionUID = 0;


final String upgrade = "Continue Upgrade";
final String restore = "Restore";

JPanel panels;
JButton flashMe;
JButton helpMe;
JTextArea Message;
JFrame newFrame;
FlasherThread flash;


protected JTextArea addText(String text, boolean visible, int fontStyle) {

    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setBackground(Color.DARK_GRAY);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
}

private UpgradePopupWindow(JFrame frame, Object ft) {

    flash = (FlasherThread)ft;
    String text = "An error occurred during the attempt to update your  software. We recommend the following: (1) Restore your device to its previous version, (2) back up important data, and then (3) try updating your device again. If you continue with the current update, only your previously backed-up data will be available.";
    addFiller(5);
    addLabel(text, Font.PLAIN, 12);
    //addText(text, true, Font.PLAIN);
    addFiller(20);
    newFrame = frame;
    flashMe = new JButton(upgrade);

    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe);


    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe);
    setOpaque(true);
    newFrame.setContentPane(this);
}

protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size)); 
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    //label.setForeground(Color.BLUE);

    add(label);
    return label;
}

protected void addFiller(int size) {
    /*
     * create some space before the progress bar
     */
    Dimension diminsion = new Dimension(size, size);
    Filler filler = new Filler(diminsion, diminsion, diminsion);
    filler.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(filler);
}

public static void createGUI(Object obj) {
    //Create and set up the frame.
   JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(400, 200));
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(frame, obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);

}


public void actionPerformed(ActionEvent e) {

    if("restore".equals(e.getActionCommand())) {
        System.out.println("restore button selected");
        flash.setUpgradeRestoreChoice("restore");
        newFrame.dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
        System.out.println("upgrade button selected");
        flash.setUpgradeRestoreChoice("upgrade");
        newFrame.dispose();
    }
}

}alt text

alt text

+2  A: 

I don't see you using any kind of Layout. Swing design works on layouts, and then populating your containers with items inside of those layouts. My personal favorite layout to use is the MigLayout.

There is plenty of support on the web page. Once you start using layouts your life will get a lot easier when it comes to design in swing.

jsmith
I barely understand BoxLayout, can you elaborate a bit more as to how I can introduce any kind of a layout into this setup?
LambeauLeap
+3  A: 

Changing the contentPane of the frame is not necessary. You can just add your JPanel to the frame. It will fill the frame by default.

JLabel does not do automatic line wrapping.

One option is to insert line breaks manually. JLabel accepts a subset of HTML:

String text = "<html>An error occurred during the attempt to update your  software. <br />We recommend the following:<br />(1) Restore your device to its previous version,<br />(2) back up important data, and then<br />(3) try updating your device again.<br />If you continue with the current update, only your previously backed-up data will be available.</html>";

Another option is to use a JTextArea in place of the label. It does not accept HTML but it can wrap lines automatically and you can include newline characters in the text to force line breaks.

Don't forget to remove the border and make the background transparent (calling setOpaque(false) only works with some look-and-feels and not others.)

Either way you need to set a layout on your JPanel.

Here's an example using GridBagLayout:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.Box.Filler;


public class UpgradePopupWindow extends JPanel implements ActionListener {
//public static UpgradePopupWindow mainWindow;

static final long serialVersionUID = 0;


final String upgrade = "Continue Upgrade";
final String restore = "Restore";

JPanel panels;
JButton flashMe;
JButton helpMe;
JTextArea Message;
JFrame newFrame;
FlasherThread flash;


protected JTextArea addText(String text, boolean visible, int fontStyle) {

    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, 12)); //$NON-NLS-1$

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setBackground(Color.DARK_GRAY);
    textArea.setForeground(Color.WHITE);
    textArea.setOpaque(false);
    textArea.setVisible(visible);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea);

    return textArea;
}

protected JTextArea addMultiLineLabel(String text, int fontStyle, int fontSize, Object constraints) {

    JTextArea textArea = new JTextArea(text);

    textArea.setFont(new Font("SansSerif", fontStyle, fontSize));

    textArea.setLineWrap(true);
    textArea.setWrapStyleWord(true);
    textArea.setEditable(false);
    textArea.setBackground(new Color(0, 0, 0, 0)); // Zero alpha = transparent background
    textArea.setOpaque(false);
    textArea.setBorder(null);
    textArea.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(textArea, constraints);

    return textArea;
}


private UpgradePopupWindow(JFrame frame, Object ft) {

    super(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    flash = (FlasherThread)ft;
    String text = "An error occurred during the attempt to update your  software.\nWe recommend the following:\n (1) Restore your device to its previous version,\n (2) back up important data, and then\n (3) try updating your device again.\nIf you continue with the current update, only your previously backed-up data will be available.";
    addFiller(5);
    gbc.gridy = 0;
    gbc.gridx = 0;
    gbc.gridwidth = 2;
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    addMultiLineLabel(text, Font.PLAIN, 12, gbc);
    addFiller(20);
    newFrame = frame;

    gbc.gridy = 1;
    gbc.gridwidth = 1;
    gbc.fill = GridBagConstraints.NONE;
    flashMe = new JButton(upgrade);
    flashMe.setActionCommand("upgrade");
    flashMe.addActionListener(this);
    flashMe.setEnabled(true);
    add(flashMe, gbc);

    ++ gbc.gridx;
    helpMe = new JButton(restore);
    helpMe.setActionCommand("restore");
    helpMe.addActionListener(this);
    helpMe.setEnabled(true);
    add(helpMe, gbc);
    setOpaque(true);
    newFrame.add(this);
}

protected JLabel addLabel(String text, int fontStyle, int size) {
    JLabel label = new JLabel(text);
    label.setFont(new Font("SansSerif", fontStyle, size)); 
    label.setAlignmentX(Component.CENTER_ALIGNMENT);
    label.setOpaque(false);
    label.setVisible(true);
    //label.setForeground(Color.BLUE);

    add(label);
    return label;
}

protected void addFiller(int size) {
    /*
     * create some space before the progress bar
     */
    Dimension diminsion = new Dimension(size, size);
    Filler filler = new Filler(diminsion, diminsion, diminsion);
    filler.setAlignmentX(Component.CENTER_ALIGNMENT);

    add(filler);
}

public static void createGUI(Object obj) {
    //Create and set up the frame.
   JFrame frame = new JFrame("PopUp Dialog");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(400, 200));
    //create and setup the content pane
    UpgradePopupWindow popUpContentPane = new UpgradePopupWindow(frame, obj);

    popUpContentPane.setOpaque(true);
    frame.setContentPane(popUpContentPane);

    frame.pack();
    frame.setVisible(true);

}


public void actionPerformed(ActionEvent e) {

    if("restore".equals(e.getActionCommand())) {
        System.out.println("restore button selected");
        flash.setUpgradeRestoreChoice("restore");
        newFrame.dispose();
    } else if ("upgrade".equals(e.getActionCommand())) {
        System.out.println("upgrade button selected");
        flash.setUpgradeRestoreChoice("upgrade");
        newFrame.dispose();
    }
}

}
finnw
sweet that helps, although I had one other question. What controls the background color for this dialog? I would want the default GRAY/light gray default background color.
LambeauLeap
Also, is there is way to normalize the text so that the left and right borders of the JTextArea are even and equidistant from the edges of the dialog box?
LambeauLeap
Some pointers here: http://stackoverflow.com/questions/200106/java-changing-swing-background-colour
finnw
Changing text justification in a JTextArea is slightly more complicated. See http://forums.sun.com/thread.jspa?threadID=5233132
finnw
Is there a better way to implement this solution with a simpler layout avoid the GridBagLayout?
LambeauLeap
One possibility is to nest two `JPanel` s, the outer one with a `BorderLayout` and the inner one (docked to the bottom edge and containing the two buttons) with a `BoxLayout`. I'm not sure it would be simpler though.
finnw
+4  A: 
  1. You should be using a better layout manager than the default
  2. You should use JOptionPane instead of making your own option dialog
davetron5000
+1 for JOptionPane
finnw