1

I am new to Swing. I am building a JFrame with a JScrollPane inside it using Eclipse IDE. Inside of the JScrollPane is a JPanel in Border Layout. I tried to add a JButton (called "submitAnswers") to the JFrame using the code below, but for some reason the button only appears at the end of the frame on my computer, but not on other computers (my friend tried it on his Mac and I tried it on a separate Windows OS like mine). Some proposed solutions that I have tried and from other sites that have not worked include:

  • Use the pack() method. Reason: since the preferred size of the JPanel is much longer in height than the JFrame (hence I employed a JScrollPane), packing the JFrame only causes the text to be not visible on the desktop.
  • Place button on content JPanel. Reason: I don't know. It just wouldn't appear on another desktop computer or my friend's mac computer.
  • Use BorderLayout.SOUTH instead of BorderLayout.PAGE_END. Reason: There was absolutely no change. The button would still be visible on my computer, but invisible on others.
  • Place button directly on JFrame. Reason: I don't know.

In addition, my JFrame is nested within a static method; hence, I've only included the relevant code for the specific method I'm having issues with.

Has anyone had this issue before? I would really appreciate your insight.

Code:

    public static void createTestPage() {

    JFrame testFrame = new JFrame("testing...1,2,3");

    //Customizes icon to replace java icon
    try {
        testFrame.setIconImage(ImageIO.read(new File("src/icon.png")));
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    //Centers location of introFrame to center of desktop
    Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
    testFrame.setLocation(screenDimensions.width / 16,screenDimensions.height / 14);

    //Size and display the introFrame.
    Insets insets = testFrame.getInsets();

    //Format size of screen itself
    testFrame.setSize(1200 + insets.left + insets.right,
                  400 + insets.top + 250 + insets.bottom);

    //Temporarily set screen so that it cannot be resized
    testFrame.setResizable(false);

    //Set background color of testFrame
    testFrame.getContentPane().setBackground(new Color(75, 0, 130));

    testFrame.setLayout(new BorderLayout());

    //Set layout of testFrame
    testFrame.setLayout(new BorderLayout(10, 1));

    //Test content
    JPanel testContentPanel = new JPanel();
    testContentPanel.setBackground(new Color(75, 0, 130));
    testContentPanel.setSize(new Dimension(900,2060));
    testContentPanel.setPreferredSize(new Dimension(900, 2060));

    //Test content pane layout
    testContentPanel.setLayout(new BoxLayout(testContentPanel, BoxLayout.PAGE_AXIS));

    //Create panel to hold instructions text
    JPanel instructionsPanel = new JPanel();
    instructionsPanel.setBackground(new Color(75, 0, 130));
    instructionsPanel.setLayout(new BorderLayout(10,1));

    //Create JPanel for submit answers button
    JPanel submitAnswersPanel = new JPanel(new BorderLayout());
    submitAnswersPanel.setBackground(new Color(75, 0, 130));
    submitAnswersPanel.setVisible(true);

    //Create button to submit personality test answers
    JButton submitAnswers = new JButton("Submit Answers");
    submitAnswers.setVisible(true);
    submitAnswers.setBorder(new EmptyBorder(10, 400, 10, 400));

    //Add submitAnswers button to panel
    submitAnswersPanel.add(submitAnswers);

    //Add submitAnswersPanel to test content panel
    testContentPanel.add(submitAnswersPanel);


        //Create scroll pane to allow for scrollable test (contents cannot fit one page)
    JScrollPane testScrollPane = new JScrollPane();
    testScrollPane.setViewportView(testContentPanel);

    //Get rid of horizontal scroll bar and add vertical scrollbar
    testScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    testScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    //Speed up scrolling
    testScrollPane.getVerticalScrollBar().setUnitIncrement(16);

    testFrame.add(testScrollPane);

    //Experiment to show button
    testFrame.setVisible(true);
    }
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 2
    Please edit your question to include an [mctre](http://stackoverflow.com/help/mcve) that exhibits the problem you describe; for consistency, use `UIManager` icons, as shown [here](http://stackoverflow.com/a/12228640/230513). – trashgod Feb 25 '14 at 20:14
  • 1
    `testContentPanel.setPreferredSize(new Dimension(900, 2060));` 1) Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement or sizing of components. To organize the components for a robust GUI, instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556), along with layout padding & borders for [white space](http://stackoverflow.com/q/17874717/418556). 2) That is taller than my screen! – Andrew Thompson Feb 25 '14 at 20:25
  • Whenever you have a panel with a BorderLayout, be sure that when you're adding a component, you use a specific location, e.g., BorderLayout.SOUTH. Currently, you have 'submitAnswersPanel.add(submitAnswers);` without specifying where in the layout the button should appear. – David Koelle Feb 25 '14 at 20:42
  • Also, I would pass testContentPanel directly to the JScrollPane constructor. (if any of these suggestions fix your problem, let me know and I'll add them as the answer) – David Koelle Feb 25 '14 at 20:43
  • Try 'testFrame.getContentPane().add(testScrollPane);' and 'testFrame.getContentPane().setLayout(new BorderLayout());' (adding getContentPane() to both) – David Koelle Feb 25 '14 at 20:44
  • Hello Andrew, thank you for the feedback. However, I do have a JPanel that is BorderLayout within the JScrollPane. Does this mean if I remove the sizing component and just add additional components or containers to the JPanel within the JScrollPane, the components will appear and the JPanel will resize automatically? The reason I asked is that I tried this method with a JLabel, but the text was cut off at the bottom since my JLabel was too long. What do you suggest I do in this case? – user3051111 Feb 25 '14 at 20:44
  • Hey David, I tried both of your suggestions, but neither of them worked. Unfortunately my button is still invisible on separate computers. – user3051111 Feb 25 '14 at 20:45
  • Don't do this: testContentPanel.setSize(new Dimension(900,2060)); - instead, only call setSize on testFrame; otherwise, let the UI components set their own sizes based on their parents' layouts. – David Koelle Feb 25 '14 at 20:46
  • Hello David, I got rid of the testContentPanel.setSize(...) method, but for some reason my JTables are now extended way past the viewport (they are not centered in the frame's content panel). I can only see the left column of a 2-column JTable. How do I fix the components so that the JTables are centered within the viewport? – user3051111 Feb 26 '14 at 06:33

1 Answers1

0

I've refactored your code a little to use method to create the individual components of the GUI. You can find the full code at this ideone link

What I saw when I first copied your code to my machine was that the only thing visible was the button. So I create all the components in their own methods and then added them to the frame and panels using the Border Layout. This then enabled me to put the instructions in the NORTH sections, the button in the SOUTH section and then the main bits would go in the CENTER section.

One thing to note about the sections: (From the documentation)

The components are laid out according to their preferred sizes and the constraints of the container's size. The NORTH and SOUTH components may be stretched horizontally; the EAST and WEST components may be stretched vertically; the CENTER component may stretch both horizontally and vertically to fill any space left over.

So you should add the component you want to scale in size to the CENTER section.

My main method now looks like this:

public static void main(final String[] args) {
    final JButton submitAnswers = createSubmitAnswersButton();
    final JPanel instructionsPanel = createInstructionsPanel();

    final JPanel testContentPanel = createContentPanel();
    testContentPanel.add(instructionsPanel, BorderLayout.NORTH);
    testContentPanel.add(submitAnswers, BorderLayout.SOUTH);

    final JScrollPane scrollingContentPane = createScrollPaneFor(testContentPanel);

    final JFrame testFrame = createJFrame();
    testFrame.add(scrollingContentPane, BorderLayout.CENTER);

    testFrame.setVisible(true);
}
Dan Temple
  • 2,736
  • 2
  • 22
  • 39
  • Hello Dan, Thank you for your suggested formatting. I have edited the code by making everything border layout and placing the button on BorderLayout.SOUTH and the instructions in BorderLayout.NORTH, and put about 4 JLabels, 8 JRadioButtons, and 4 JTables in BorderLayout.CENTER. However, I am still having the same issue and more. First, the button only appears on my computer but not on another desktop computer. Second, only the last 2 radio button appear in the center. My code is below. – user3051111 Feb 26 '14 at 21:05
  • The content pane on your Frame is a single panel. It can hold 5 components using the BorderLayout. Those components can then be JPanels which can in turn hold more components. If you add a JTable to BorderLayout.CENTER of the frame, then add another one to the same region of the frame, you'll end up loosing components. You need to add them to individual panels and scroll panes and then nest those in order to achieve your desired display. Or use another layout manager, like [GroupLayout](http://docs.oracle.com/javase/7/docs/api/javax/swing/GroupLayout.html) – Dan Temple Feb 27 '14 at 08:24
  • I've put an example with this nesting panels stuff [at this ideone link](https://ideone.com/8QExa1) – Dan Temple Feb 27 '14 at 08:37
  • Thank you so much for your invaluable help Dan. Now everything is formatted correctly EXCEPT the button is still not visible. I used the exact same formatting scheme that you shared with me at that ideone link. I placed the button on the testContentPanel using BorderLayout.SOUTH. Does the button show up when you run the program? – user3051111 Feb 28 '14 at 20:13
  • Yes it does, but its at the bottom of the window, so you need to scroll to get to it. – Dan Temple Mar 02 '14 at 11:34