I've written a few small Java programs with Swing. They work fine when I run them through Netbeans, but when I run them as a jar outside of Netbeans, the Swing elements render partially or not at all.
Here's a comparison:
Through Netbeans:
Outside of Netbeans:
Some of the issues arise as soon as the frame appears, and others when I move the cursor over an element. The main problems are that the text isn't rendering and the button text, border and background appears and disappears randomly. The frame's border is not an issue. The difference between the two screenshots is simply a result of the clear frames in Windows 7 and which windows I had open under the program when I made the screenshots.
Here's a streamlined version of the GUI code minus event handling and program logic:
package alarmclock;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class AlarmClockGUI {
private JFrame frame;
private JButton onOffButton;
private JComboBox<String> alarmList;
private JLabel remainingTime, currentTime,
alarmTime;
private final EventHandler eventHandler; //Handles GUI events
private final boolean time24Mode = false; //Indicates 24H (true) or 12H (false) time
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
AlarmClockGUI acg = new AlarmClockGUI();
}
});
}
public AlarmClockGUI() {
eventHandler = new EventHandler(); //Handles GUI events
createFrameOptions();
}
class EventHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//Code added here
}
}
private void updateTimeDisplay() {
String tempTime = String.format("%tT", new Date());
if (time24Mode) {
currentTime.setText(tempTime);
} else {
currentTime.setText(String.format("%tr", new Date()));
}
}
private void createFrameOptions() {
frame = new JFrame("Alarm Clock");
frame.getContentPane().add(createMainPanel());
createTimer(); //must follow main panel creation
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.pack();
frame.setLocationRelativeTo(null); //Centers frame. Must follow pack()
frame.setVisible(true);
}
private JPanel createTimePanel() {
JPanel timePanel = new JPanel(new GridBagLayout());
remainingTime = new JLabel("00:00:00", SwingConstants.CENTER);
remainingTime.setFont(
remainingTime.getFont().deriveFont(36.0f));
remainingTime.setPreferredSize(new Dimension(164, 80));
remainingTime.setOpaque(true);
remainingTime.setBorder(
BorderFactory.createTitledBorder("Remaining Time"));
currentTime = new JLabel(String.format("%tT", new Date()),
SwingConstants.CENTER);
currentTime.setFont(
currentTime.getFont().deriveFont(16.0f));
currentTime.setPreferredSize(new Dimension(164, 40));
currentTime.setOpaque(false);
currentTime.setBorder(
BorderFactory.createTitledBorder("Current Time"));
alarmTime = new JLabel("00:00:00", SwingConstants.CENTER);
alarmTime.setFont(
alarmTime.getFont().deriveFont(16.0f));
alarmTime.setPreferredSize(new Dimension(164, 40));
alarmTime.setOpaque(false);
alarmTime.setBorder(
BorderFactory.createTitledBorder("Alarm Time"));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.gridheight = 2;
c.fill = GridBagConstraints.VERTICAL;
timePanel.add(remainingTime, c);
c.gridx = 1;
c.gridheight = 1;
c.fill = GridBagConstraints.NONE;
timePanel.add(currentTime, c);
c.gridy = 1;
timePanel.add(alarmTime, c);
return timePanel;
}
private JComboBox createAlarmList() {
alarmList = new JComboBox<>();
alarmList.addActionListener(eventHandler);
alarmList.setActionCommand("List");
alarmList.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
return alarmList;
}
private JPanel createButtonPanel() {
JPanel buttonPanel = new JPanel();
onOffButton = createButton("Alarm Off", eventHandler);
onOffButton.setPreferredSize(new Dimension(88, 26));
buttonPanel.add(createButton("New Alarm", eventHandler));
buttonPanel.add(createButton("Edit", eventHandler));
buttonPanel.add(onOffButton); //Not anonymous; button text changes
buttonPanel.add(createButton("Delete", eventHandler));
return buttonPanel;
}
private JButton createButton(String buttonName, ActionListener al) {
JButton b = new JButton(buttonName);
b.setActionCommand(buttonName);
b.addActionListener(al);
return b;
}
private JPanel createMainPanel() {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
mainPanel.add(createTimePanel());
mainPanel.add(Box.createRigidArea(new Dimension(10, 10)));
mainPanel.add(createAlarmList());
mainPanel.add(Box.createRigidArea(new Dimension(0, 10)));
mainPanel.add(createButtonPanel());
mainPanel.setBorder(
BorderFactory.createEmptyBorder(10, 10, 10, 10));
return mainPanel;
}
private void createTimer() {
Timer timer = new Timer(1000, eventHandler);
timer.setActionCommand("Timer");
timer.setInitialDelay(0);
timer.start();
}
}
I just updated my JRE to the latest build (the problem was occurring before that as well), and Netbeans is using the same JRE as the rest of my system.
Does anyone have some insight as to why my programs are rendering incorrectly outside of Netbeans?
---Update---------------------
I tried setting the Look and Feel as was suggested, but that didn't help.