Results 1 to 6 of 6
  1. #1
    yohohoho is offline Member
    Join Date
    Nov 2013
    Posts
    3
    Rep Power
    0

    Default Bizarre GUI/jar behavior outside of Netbeans

    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:

    Bizarre GUI/jar behavior outside of Netbeans-2nxlx.png

    Outside of Netbeans:

    Bizarre GUI/jar behavior outside of Netbeans-rcctd.png

    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:

    Java Code:
        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?

  2. #2
    yohohoho is offline Member
    Join Date
    Nov 2013
    Posts
    3
    Rep Power
    0

    Default Re: Bizarre GUI/jar behavior outside of Netbeans

    After some more research, I discovered that this problem may be related to setting certain system properties on the JRE or explicitly in the program. Specifically, I was able to add:

    System.setProperty("sun.java2d.d3d", "false");

    to the main method, and that cleared up my problem. Turns out that Netbeans starts up the JVM with that exact property, which explains why it worked fine in Netbeans, but not outside of it.

    A similar issue is referred to here, and here is what Oracle says about the property. Apparently the property can be explicitly set as a flag on the JVM, but I haven't had much luck in getting it to work on my machine, so I've set it in the program instead.

  3. #3
    gimbal2 is online now Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,008
    Rep Power
    6

    Default Re: Bizarre GUI/jar behavior outside of Netbeans

    You set system properties with the -D command line property using the following syntax

    -Dproperty.name=value

    so in this particular case you would use:

    java -Dsun.java2d.d3d=false -jar bla.jar

    Its a bit weird that you need to disable Direct3D, especially because you're on Windows 7 which demands that your video card and drivers are up to snuff for it to function itself. On the other hand, Java2D/Swing is likely not tuned for anything above Windows Vista now that JavaFX 2 is around. It might help if you set different look & feels though.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

  4. #4
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,236
    Rep Power
    7

    Default Re: Bizarre GUI/jar behavior outside of Netbeans

    Java Code:
    remainingTime.setPreferredSize(new Dimension(164, 80));
    You should also NOT be using setPreferredSize(...).

    Let the layout manager determine the size. Use nested layout when necessary.

  5. #5
    yohohoho is offline Member
    Join Date
    Nov 2013
    Posts
    3
    Rep Power
    0

    Default Re: Bizarre GUI/jar behavior outside of Netbeans

    Quote Originally Posted by gimbal2 View Post
    You set system properties with the -D command line property using the following syntax

    -Dproperty.name=value

    so in this particular case you would use:

    java -Dsun.java2d.d3d=false -jar bla.jar

    Its a bit weird that you need to disable Direct3D, especially because you're on Windows 7 which demands that your video card and drivers are up to snuff for it to function itself. On the other hand, Java2D/Swing is likely not tuned for anything above Windows Vista now that JavaFX 2 is around. It might help if you set different look & feels though.
    I found that using System.setProperty() was the only way to have the property set when running a jar file without the command line. I've been trying to figure out if there is a way to set my JRE to start with -Dsun.java2d.d3d=false automatically given how often I would need to set this flag in my programs. Not to mention that the Java Control Panel itself exhibits the same behavior as my Swing programs have been, and apparently it uses Swing.

    I'm just as surprised that this ended up being the solution to my problem. My program worked fine on a friend's computer running Windows 7.

    Quote Originally Posted by camickr View Post
    Java Code:
    remainingTime.setPreferredSize(new Dimension(164, 80));
    You should also NOT be using setPreferredSize(...).

    Let the layout manager determine the size. Use nested layout when necessary.
    On one of the buttons in particular I set the size explicitly because the button's text changes when it is toggled, and the difference in text length causes the button to change size. Is there a better solution to that problem?

    Further, the panel which displays the time and alarms uses a GridBagLayout, and Oracle's Java tutorial says that components in this layout are sized based on the preferred size. If I don't specify the sizes, the components end up being too small and out of alignment with the rest of the GUI. Do you have a recommendation for that?

  6. #6
    gimbal2 is online now Just a guy
    Join Date
    Jun 2013
    Location
    Netherlands
    Posts
    4,008
    Rep Power
    6

    Default Re: Bizarre GUI/jar behavior outside of Netbeans

    Quote Originally Posted by yohohoho View Post
    I found that using System.setProperty() was the only way to have the property set when running a jar file without the command line.
    Well you could use a jar wrapper tool to create an executable with all the basic properties pre-set in them. But indeed, your solution is also fine especially if you want to always disable it and not make it optional.
    "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis

Similar Threads

  1. Replies: 7
    Last Post: 03-21-2012, 06:18 AM
  2. Bizarre screen distortion
    By morello in forum New To Java
    Replies: 1
    Last Post: 12-21-2011, 03:28 PM
  3. Most BIZARRE problem ever ( Need Advance People )
    By trupsterful in forum Advanced Java
    Replies: 11
    Last Post: 06-12-2011, 04:17 AM
  4. the most Bizarre problem EVER.
    By trupsterful in forum Java Applets
    Replies: 3
    Last Post: 05-19-2011, 05:49 PM
  5. bizarre auto expansion
    By fishtoprecords in forum Suggestions & Feedback
    Replies: 2
    Last Post: 07-31-2008, 10:52 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •