JScrollPane not showing up for JList - java

I'm trying to add a JScrollPane to my JList but for whatever reason it isn't working. I've read several tutorials both on here and other sites and it seems i'm following the directions correctly. I've tried it using both a DefaultListModel and no DefaultListModel seeing if it would make a difference. I've also tried resizing the widget itself and that doesn't work, either.
Here is my code. itemNames is an array of Strings[] which contain various souvenir names that i'm adding to the JList. i'm using BorderLayout() and the panel i'm attempting to add the JScrollPane to is utilizing a GridBagLayout():
souvenirList = new JList(itemNames);
souvenirList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
souvenirList.setLayoutOrientation(JList.VERTICAL);
souvenirList.setVisibleRowCount(-1);
scrollPane = new JScrollPane(souvenirList);
gbc3.gridx = 1;
gbc3.gridy = 1;
centerPanel.add(scrollPane, gbc3);
c.add(centerPanel, BorderLayout.CENTER);
The box shows up with the names in it, but no JScrollPane :( I was hoping someone could help me out, maybe point out a simple mistake I may be making. Thanks to all in advance. Please don't post links to tutorials on the topic cus believe me, i've read them thoroughly.
EDIT: In this small runnable example I built, using mostly code from my previous snippet, the bar shows up fine! Why could this be? Could it have something to do w the JPanel i'm adding it to? Or maybe the GridBagLayout? I'm so confused here....
import javax.swing.*;
import java.awt.*;
public class JScroll extends JFrame
{
JList souvenirList;
JScrollPane scrollPane;
Container c = getContentPane();
private String[] itemNames = {"mug","cap","tee shirt","sweat shirt","pennant","mini stick",
"bobblehead","paper bag","foam paw","thunderstix"};
public JScroll()
{
setLayout(new FlowLayout());
souvenirList = new JList(itemNames);
souvenirList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
souvenirList.setLayoutOrientation(JList.VERTICAL);
//souvenirList.setVisibleRowCount(-1);
scrollPane = new JScrollPane(souvenirList);
c.add(scrollPane);
}
public static void main(String[] args)
{
JScroll frame = new JScroll();
frame.setSize(400,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

The issue was centered around the fill() method within GridBagLayout(). I didn't notice it was set to VERTICAL, meaning the JList was going to request more vertical space. Changing to HORIZONTAL fixed the issue.

Related

Dynamic changing of layouts in swing

I am almost certain this question was asked before here: Java Swing: How to change GUI dynamically , but I seem to just have some fundamental misunderstanding in how it works.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class JTest extends JFrame
{
public static void main(String[] args)
{
JTest t = new JTest();
}
Container pane;
public JTest()
{
setSize(500,500);
setTitle("JTest");
setDefaultCloseOperation(EXIT_ON_CLOSE);
pane = getContentPane();
pane.setLayout(new GridLayout(1,2));
JButton old = new JButton("old");
old.addActionListener(new OldButton());
pane.add(old);
JScrollPane scroll = new JScrollPane(new JTextArea(50,20));
pane.add(scroll);
setVisible(true);
}
private class OldButton implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
pane.setLayout(new GridLayout(1,2));
JButton old = new JButton("new");
old.addActionListener(new NewButton());
pane.add(old);
JScrollPane scroll = new JScrollPane(new JTextArea(50,20));
pane.add(scroll);
pane.validate();
}
}
private class NewButton implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
pane.setLayout(new GridLayout(1,2));
JButton old = new JButton("old");
old.addActionListener(new OldButton());
pane.add(old);
JScrollPane scroll = new JScrollPane(new JTextArea(50,20));
pane.add(scroll);
pane.validate();
}
}
}
This code should replace the preexisting layout with a new one anytime the button in the corner is pressed, but instead, it just adds the new layout to the frame. Can someone tell me what I'm doing wrong?
EDIT:
Adding some information. A picture for reference:
I'm making a set of components like this inside the scroll pane. whenever I press the "Make new field" button, I want it to add a "field" (the name of the field followed by a textarea or some such) to the set in that scrollpane. This means changing the layout of the area inside the scrollpane to include the new field.
OK -- so it looks like what you want to do (and please correct me if I'm wrong) is to add a new component to a JPanel that is displayed within a JScrollPane. If so, then you do not want to change or swap layouts, and you certainly don't want to keep adding new JScrollPanes. Instead consider doing:
Create one JScrollPane and add to your GUI. Don't re-add this as you'll only need one.
add a JPanel to the JScrollPane's viewport that uses a layout that allows multiple components to be easily added to it. Perhaps a GridLayout or a BoxLayout, depending on what you need.
Also consider not adding the above JPanel directly to the viewport but rather adding it to another JPanel, one that uses BorderLayout, adding the first JPanel to the BorderLayout-using JPanel's BorderLayout.PAGE_START position, and then add this to the JScrollPane's viewport. This way the first JPanel won't stretch to fill the viewport initially.
Then in your button's ActionListener, add your components to the first JPanel by calling .add(...) on it, and then call revalidate() and repaint() on that first JPanel to layout the newly added components and repaint the JPanel and its contents.
Ok, so it turns out this wasn't a layout problem at all. I had failed to realize that setting a new layout doesn't cause the previous layout's components to disappear, you have to remove them before adding the new components. That's why I was getting duplication.
Thanks for pointing me in the right direction, though.

JPanel in JScrollPane not showing [duplicate]

This question already has answers here:
Why is my table not visible when it's in a JScrollPane?
(2 answers)
Closed 8 years ago.
I'm busy making a level designer for a game I'm planning to make in Java. I have a panel for settings, for example the size of the level or what the background will be. You can also select images to put on the other panel, the 'DesignerPanel' and then you should be able to click on that panel to put it in a specific place. I put the DesignerPanel in a JScrollPane to scroll around bigger levels.
The problem is that the JScrollPane doesn't appear and neither does the panel that should be in it. I have found some questions about the scroll bars not appearing, but in my case nothing appears. Well, at least, almost nothing.
You can see really small stripes of the DesignerPanel to the right and below. However, there is no trace of the JScrollPane or the rest of the panel. Resizing or minimizing and unminimizing the screen doesn't make a difference. I would post an image and I think it would surely help, but apparently I need reputation to do that, so sorry about that.
Here's the relevant code I have so far. I have hidden most of the code because it is not important for this error.
package games;
import java.awt.*;
import java.io.*;
import javax.swing.*;
class LevelDesignerScreen extends JFrame
{
private SettingsPanel sp;
private DesignerPanel dp;
private JScrollPane scroller = new JScrollPane();
LevelDesignerScreen()
{
sp = new SettingsPanel(this);
add(sp, BorderLayout.WEST);
dp = new DesignerPanel(sp);
dp.setSize(1000, 1000);
scroller.setPreferredSize(new Dimension(600, 600));
scroller.add(dp);
add(scroller, BorderLayout.CENTER);
}
public static void main(String[] args)
{
new LevelDesignerScreen();
}
}
You should use
scroller = new JScrollPane(dp);
or
scroller.setViewportView(dp);
instead of scroller.add(dp).
And on a more general note: if you are having problems with layout, put prime colored line borders on all involved components to see what takes up space and what doesn't.

Getting scrollbar to work with absolute positioning on

Hello I'm trying to make a game and a basic thing I want to do is add a JTextArea with a scrollbars. This is my code:
package TestStuff;
import javax.swing.*;
#SuppressWarnings("serial")
public class JTextAreaTest extends JFrame
{
public static void main(String[] args)
{
new JTextAreaTest();
}
public JTextAreaTest()
{
this.setSize(1500, 600);
setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
this.setLocation(450, 175);
this.setExtendedState(JFrame.
MAXIMIZED_BOTH);
this.setTitle("Game Display Test");
panel1 = new JPanel(null);
final JTextArea gameDisplay = new JTextArea(
500, 300);
gameDisplay.setBounds(424, 300, 500, 300);
gameDisplay.setBackground(Color.BLACK);
Font font = new Font ("Verdana", Font.BOLD,
14);
gameDisplay.setFont(font);
gameDisplay.setForeground(Color.WHITE);
final JScrollPane displayScroll = new JScrollPane(
gameDisplay);
displayScroll.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_
NEEDED);
displayScroll.setVerticalScrollBarPolicy(
JScrollPane.
VERTICAL_SCROLLBAR_AS_NEEDED);
panel1.add(gameDisplay);
panel1.add(displayScroll);
setContentPane(panel1);
this.setVisible(true);
}
}
Everything workable fine when I run it, but when the text gets out of the bounds of the JTextArea, the scrollbars never appear! And yes, I know I'm using absolute positioning (no layout) and that's bad but I need it for other reasons in my game. Thanks in advance! (Also I can't connect to this site for some reason on my computer but I've used you guys before and you're awesome, so I have to type this on my phone. Sorry if the layout of the question gets screwed up, it the phone :P)
When you call...
panel1.add(gameDisplay);
panel1.add(displayScroll);
You are effectively removing the gameDisplay from displayScroll, as a component can only have one parent.
The fact that it works as it does comes down to the fact that you are playing around with the position and size of the gameDisplay panel instead of the displayScroll, which you should be...
Use
panel1.add(displayScroll);
Instead, but make sure you size and position ONLY the displayScroll, as displayScroll will take care of the gameDisplay
I had a similar problem and the solution was setPreferredSize on the component inside the scrollbar. I was trying to absolute position things inside the scrollbars. Luckily I knew exactly what the size should be. Maybe this is a special case.
final JFrame frame = new JFrame("HelloWorldSwing");
final JPanel panel = new JPanel();
panel.setPreferredSize(PUT SIZE HERE);
panel.setLayout(null);
final JScrollPane scrollPane = new JScrollPane(panel);
frame.getContentPane().add(scrollPane);

GUI Disappearing when I add JComboBox

Alright I'm relatively new to programming and it may be just something simple that I'm missing but the other threads related to this topic the poster didn't give adequate information relative to their issue for others to provide quality answers so I will give it a shot.
public BenchUI(JFrame j){
jf = j;
init();
add(mainPanel);
topPanelButtons();
selectedCustomer();
rentalOptions();
clientListBox();
}
At this point i can point out that everything works perfectly until I add the clientListBox() method. (below)
public void clientListBox(){
clientList = new JComboBox(moo);
clientList.setPreferredSize(new Dimension(460,30));
gbc.gridx = 0;
gbc.gridy = 0;
leftSide.add(clientList,gbc);
}
i can comment it out and get my whole GUI back working perfectly but without a JComboBox.
moo is String [] moo = {"Fish","Goat", "Monkey"};
a dummy string just for testing purposes and initialized at the start.
So any idea why my GUI completely disappears when I place in the clientList?
If anything else is necessary I'll be watching this thread and can provide additional information.
As a side note I keep getting warnings for "Raw Types" but it works without specifiying, could I potentially run into trouble by not specifying my JComboBox?
EDIT:
ok I believe I've duplicated whatever the issue is in this code
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.*;
public class main {
public static void main(String[] args){
JFrame jf = new JFrame();
jf.setExtendedState(JFrame.MAXIMIZED_BOTH);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setResizable(false);
BenchUI bu = new BenchUI(jf);
jf.add(bu);
}
}
public class BenchUI extends JPanel{
JPanel one;
JFrame jf;
JComboBox<String> clientList;
String[] moo = {"Goat", "Fish", "Donkey"};
public BenchUI(JFrame j){
jf = j;
one = new JPanel(new GridBagLayout());
one.setBackground(Color.blue);
one.setPreferredSize(new Dimension(300,300));
clientList = new JComboBox<String>(moo);
one.add(clientList);
add(one);
}
}
with the clientList stuff commented out I get my silly little blue panel and once it is added I lose the blue panel and the combobox doesnt show up as well...betting on this is a facepalm issue at this point >.<
EDIT: to include the main class.
EDIT: took out the comment marks for the JComboBox constructor and implementer
Your posted sort of sscce-like (not a real SSCCE by the way since we can't run it) code doesn't add any such as the JComboBox to the JPanel and adds no components such as the current JPanel to the JFrame.
public class BenchUI extends JPanel{
JPanel one;
JFrame jf;
JComboBox<String> clientList;
String[] moo = {"Goat", "Fish", "Donkey"};
public BenchUI(JFrame j){
jf = j;
one = new JPanel(new GridBagLayout());
one.setBackground(Color.blue);
one.setPreferredSize(new Dimension(300,300));
//clientList = new JComboBox<String>(moo);
//one.add(clientList);
add(one);
}
}
and so it makes sense that none of the components will show up on any JFrame. You will want to read the Swing tutorials on how to add components to other components (or containers) and how to create and show a JFrame. Have a look at How to Use Swing Components.
Edit
Your latest code now does in fact add the BenchUI JPanel to the JFrame, but still you add no components to the BenchUI JPanel, and in fact you don't even construct your JComboBox but only create a JComboBox variable. Again, I strongly urge you to read the Swing tutorials which I've linked to above as well as the general Java tutorials.
Edit 2
Some general advice:
If you want to add a component to a GUI you must first create the component object. You are declaring your clientList JComboBox, but you never create the object.
Then you must add the component object to a container that eventually will be part of the hierarchy leading to a top level window such as a JFrame, JDialog, JApplet and such. You never add a clientList object to the GUI.
You should add your components to the top level window before calling pack() on the top level window -- which tells all the layout managers to lay out all the components they hold.
You should then call setVisible(true). One problem with your code (other than not creating important components and not adding them to the GUI!) is that you're calling setVisible(true) on your JFrame way too early before adding anything to the GUI.
Read the Swing tutorial, but especially the one on using layout managers and on adding components to a top level window.
Edit 3
OK, now you're creating your JComboBox, but you still are adding all components to your JFrame after setting it visible. Please re-check my 3rd and 4th bullets in the bullet list above.

JTable selects wrong cell on click

I am working inside of a quite complex eclipse based application, and having a problem with a JTable based custom component inside of a JSplitPane. The part of the application that I actually have access to is a panel, within a tab, within a panel, within the actual application, so there are a lot of things that can go wrong.
The specific problem that I'm having right now is that the table component is selecting the wrong cell when I click on it. If I select a cell in row 0, column 0, the cell that actually gets selected is at row 2, column 0, which is about 20 pixels below the actual click. This only happens if the table is in a JSplitPane though: if I just add the table itself to a panel, cell selection is correct.
What it seems like to me is that because the table is in a JSplitPane, the boundaries of the table (or maybe the viewport of the scroll pane containing the table?) are off by about 20 pixels somewhere. Another problem that I had which can back this theory up, is that scrolling the table caused repaints above the table: so for example, as I scrolled down, instead of the table scrolling, it actually moved upwards (painting over the components above the table) about 20 pixels before scrolling. I was able to workaround this problem by adding
jscrollpane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
to the scrollpane that contained the table.
Because of all the custom components involved, I can't actually get a small app that shows the problem, but I have the next best thing, which is an app that shows the layout that I have (of course, it doesn't actually have the same problems). Any ideas on what might be causing the problem?
//Test class showing layout of table/splitpane
import javax.swing.*;
import java.awt.*;
public class SplitTest
{
private static JFrame frame;
private static JPanel buildTable()
{
JPanel tblPanel = new JPanel();
tblPanel.setLayout(new BorderLayout());
String[] cols = new String[]{"one", "two", "three", "four", "five", "six", "seven"};
Object[][] data = new Object[30][7];
for(int x = 0;x < data.length;x++)
for(int y = 0;y < data[x].length;y++)
data[x][y] = x + ", " + y;
JTable tbl = new JTable(data, cols);
JScrollPane scrollPane = new JScrollPane(tbl);
tblPanel.add(scrollPane, BorderLayout.CENTER);
return tblPanel;
}
private static JPanel buildTab()
{
JPanel pnl = new JPanel();
pnl.setLayout(new BorderLayout());
JPanel menuPnl = new JPanel();
menuPnl.setLayout(new FlowLayout(FlowLayout.LEFT));
menuPnl.add(new JLabel("label"));
menuPnl.add(new JComboBox(new String[]{"one", "two"}));
menuPnl.add(new JButton("Button"));
pnl.add(menuPnl, BorderLayout.NORTH);
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setLeftComponent(buildTable());
JPanel bottomPnl = new JPanel();
bottomPnl.setPreferredSize(new Dimension(800, 200));
bottomPnl.setBackground(Color.RED);
splitPane.setRightComponent(bottomPnl);
splitPane.setDividerLocation(.5);
pnl.add(splitPane, BorderLayout.CENTER);
return pnl;
}
private static JTabbedPane buildGUI()
{
JTabbedPane topLevelTabbedFrame = new JTabbedPane();
topLevelTabbedFrame.addTab("Tab 1", buildTab());
topLevelTabbedFrame.addTab("Tab 2", new JPanel());
topLevelTabbedFrame.addTab("Tab 3", new JPanel());
return topLevelTabbedFrame;
}
private static void createAndShowGUI()
{
frame = new JFrame("Split Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(buildGUI(), BorderLayout.CENTER);
// frame.setSize(new Dimension(800, 600));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws Exception
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Because of all the custom components involved, I can't actually get a small app that shows the problem, but I have the next best thing, which is an app that shows the layout that I have (of course, it doesn't actually have the same problems).
I was about to tell you the posted code workd just fine, and the I read this.
Anyway, it seems the problem lies in all the custom components you added to the mix. For JTable and JSplitPane work fine alone.
What I would do is to remove components one by one until it works ( probably I will work when the code is similar to the one posted and there is nothing else there )
Or you can go the opposite way which is easier. Start with your sample code and then add more and more components until it fail.
You can take this opportunity to refactor and clean your code and move unneeded components. And even ( why not ) add test cases in the process.
Good luck.
Have you tries running it on a different box to check if its hardware related.
May be related to this bug
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4763448
As it turns out, the problem was with the order that the components were initialized and added to the split pane. So the eventual fix was to delay adding the table to the split pane until after the split pane was actually added to the panel, rather than adding the table to the split pane before adding the split pane to the panel. Making that small change fixed the issue.

Categories