How to make a JFrame scrollable in Java? - java

I have this code in which I am trying to fit a scrollable Panel (JPanel) but I don't get it. Here is my code:
public class Sniffer_GUI extends JFrame {
Canvas c = new Canvas();
ConnectorPropertiesPanel props;
public Sniffer_GUI() {
super("JConnector demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
init();
getContentPane().add(new JLabel("Connectors example. You can drag the connected component to see how the line will be changed"),
new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 5), 0, 0));
getContentPane().add(initConnectors(),
new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
getContentPane().add(props,
new GridBagConstraints(1, 1, 1, 1, 0, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 0, 5, 5), 0, 0));
setSize(800, 600);
setLocationRelativeTo(null);
}
Thanks in advance.
I edit to add a code that partially seems to work...
public Sniffer_GUI() {
super("JConnector demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
add(scrPane);
scrPane.setLayout(new ScrollPaneLayout());
init();
add(initConnectors());
setSize(800, 600);
setLocationRelativeTo(null);
}
But it isn't still scrollable, at least it makes its function inside a JScrollPane, is a good step.

Make a JPanel scrollable and use it as a container, something like this:
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
add(scrPane); // similar to getContentPane().add(scrPane);
// Now, you can add whatever you want to the container

To extend #Eng.Fouad answer:
public class Sniffer_GUI extends JFrame {
Canvas c = new Canvas();
ConnectorPropertiesPanel props;
public Sniffer_GUI() {
super("JConnector demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
getContentPane().add(scrPane);
container.setLayout(new GridBagLayout());
init();
container.add(new JLabel("Connectors example. You can drag the connected component to see how the line will be changed"),
new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 5), 0, 0));
container.add(initConnectors(),
new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
container .add(props,
new GridBagConstraints(1, 1, 1, 1, 0, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 0, 5, 5), 0, 0));
setSize(800, 600);
setLocationRelativeTo(null);
}
}

Maybe this will help...
JFrame frame = new JFrame();
JPanel panel = new JPanel();
// add something to you panel...
// panel.add(...);
// add the panel to a JScrollPane
JScrollPane jScrollPane = new JScrollPane(panel);
// only a configuration to the jScrollPane...
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
// Then, add the jScrollPane to your frame
frame.getContentPane().add(jScrollPane);

To make a component of a JFrame scrollable, wrap the component in a JScrollPane:
JScrollPane myJScrollPane = new JScrollPane(myJLabel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
and replace mentions of myJLabel with myJScrollPane. Worked for me.

Just chiming in, and feel free to correct me if I'm off base, but using a JScrollPane like that has an unintended consequence of requiring more frequent window resizing.
For example, I had a program where I set up a JFrame-wide scrollpane like that. I also had a JTextArea in a tab in the frame that was the same size as the content pane. This textArea was also in its own scrollpane (this was more of a screwing around project than anything else). When I loaded content from a file to deposit in the textArea, it triggered the scrollbars around the text area.
The result was that my, let's call it the innerScrollPane, was now larger than the JFrame because of the scrollbars, which hadn't been visible before. This then triggered what I'm now going to call the outerScrollPane, to display its scrollbars, which then covered up the inner scrollbars.
This was easily resolved by adding an extra window.pack() argument to the end of my file opening method, but I just wanted to throw this out there. The scrollbars can potentially cover up content in the window if you're not careful. But... well there are a million ways to prevent this problem, so it's not a huge deal. Just something to be aware of.

Try this:
JScrollPane sp = new JScrollPane();
this.add(sp).
sp.add( *GUI elements for your applications.*)
Something like that should work for you. Take a look at this as well:

Related

JTree in a JScrollPane with fixed size

I have a JTree inside a JScrollPane which is inside a JPanel.
The problem I got is the width which is not fixed when I fill the JTree with nodes, or with a node with a long name.
Here an example:
As you can see, the left one is longer then the right one.
My goal is to keep them exactly equal in size, splitting the main window at 50% each.
Here the code used to generate the window.
Is there a way to keep the width size of the JScrollPane fixed?
Thanks.
public void initialize() {
this.frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu mnNewMenu = new JMenu("Services");
mnNewMenu.setHorizontalAlignment(SwingConstants.CENTER);
menuBar.add(mnNewMenu);
frame.getContentPane().setLayout(new MigLayout("", "[grow][grow]", "[grow][grow]"));
JPanel left_JPanel = new JPanel();
frame.getContentPane().add(left_JPanel, "cell 0 0,grow");
left_JPanel.setLayout(new MigLayout("", "[grow]", "[grow]"));
left_ScrollPane = new JScrollPane();
left_JPanel.add(left_ScrollPane, "cell 0 0,grow");
JLabel left_Label = new JLabel("Left Scroll Pane");
left_Label.setFont(new Font("Tahoma", Font.BOLD, 12));
left_Label.setForeground(Color.BLUE);
left_Label.setHorizontalAlignment(SwingConstants.CENTER);
left_ScrollPane.setColumnHeaderView(left_Label);
JTree left_tree = new JTree();
left_ScrollPane.setViewportView(left_tree);
JPanel right_JPanel = new JPanel();
frame.getContentPane().add(right_JPanel, "cell 1 0,grow");
right_JPanel.setLayout(new MigLayout("", "[grow]", "[grow]"));
JScrollPane right_ScrollPane = new JScrollPane();
right_JPanel.add(right_ScrollPane, "cell 0 0,grow");
right_JTree = new JTree(phModel);
right_JTree.setVisibleRowCount(8);
right_ScrollPane.setViewportView(right_JTree);
JLabel right_Label = new JLabel("Right Scroll Pane");
right_Label.setFont(new Font("Tahoma", Font.BOLD, 12));
right_Label.setForeground(Color.BLUE);
right_Label.setHorizontalAlignment(SwingConstants.CENTER);
right_ScrollPane.setColumnHeaderView(right_Label);
}
My goal is to keep them exactly equal in size, splitting the main window at 50% each.
Use nested panels with standard layout manager from the JDK.
The GridLayout makes components the same size.
Something like:
JPanel left = new JPanel( new BorderLayout() );
left.add(leftLabel, BorderLayout.PAGE_START);
left.add(listScrollPane, BorderLayout.CENTER);
JPanel right = ...
JPanel main = new JPanel( new GridLayout(0, 2) );
main.add( left );
main.add( right );
frame.add( main );

List not updating correctly?

Ive been following TheCherno's network chat programming tutorials, and I am almost done, just fixing bugs when I ran into a problem. I have a button that opens a window that is supposed to have a list of all the connected users listed. However, everytime I test it, the only item on the list is the first person who connected to that instance of the server. It is the same for all of the other users connected as well. I have no errors in my code, and it all seems correct. I can't seem to find the error.
This function is called from a while running loop, and everything else in it is working constantly, so I don't think there is something wrong in this.
private void sendStatus() {
if (clients.size() <= 0) return;
String users = "/u/";
for (int i = 0; i < clients.size() - 1; i++) {
users += clients.get(i).name + "/n/";
}
users += clients.get(clients.size() - 1).name + "/e/";
sendToAll(users);
}
This is from another class, where the client decodes the messages sent from the server.
else if (message.startsWith("/u/")) {
String[] u = message.split("/u/|/n/|/e/");
users.update(Arrays.copyOfRange(u, 1, u.length - 1));
}
And then this is the peice that handles the graphics of it, I don't see anything wrong in it, but I will include it anyway jsut in case. Thanks all!
private JPanel contentPane;
private JList list;
public OnlineUsers() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(200, 320);
setLocationRelativeTo(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[]{0, 0};
gbl_contentPane.rowHeights = new int[]{0, 0};
gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{1.0, Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
list = new JList();
GridBagConstraints gbc_list = new GridBagConstraints();
gbc_list.fill = GridBagConstraints.BOTH;
gbc_list.gridx = 0;
gbc_list.gridy = 0;
JScrollPane p = new JScrollPane();
p.setViewportView(list);
contentPane.add(p, gbc_list);
list.setFont(new Font("Verdana", 0, 14));
}
public void update(String[] users) {
list.setListData(users);
}
Still no ideas at all. I even checked the source code that the tutorial person made and its the same thing. I would really appreciate the help, as I am 14 and just learning java. Bump.
https://github.com/TheCherno/ChernoChat

Java JTable - Transparence with Nimbus/System L&F

I have this JTable:
List<MyTuple> l= new ArrayList<>();
l.add(new Element(1,"One"));
l.add(new Element(2,"Two"));
l.add(new Element(3,"Three"));
l.add(new Element(4,"Four"));
l.add(new Element(5,"Five"));
l.add(new Element(6,"Six"));
l.add(new Element(7,"Seven"));
JScrollPane pane = new JScrollPane();
pane.setOpaque(false);
pane.setBorder(new EmptyBorder(0, 0, 0, 0));
pane.setBackground(new Color(0,0,0,0));
pane.setFont(new Font("Segoe UI Semibold", Font.PLAIN, 12));
pane.setBounds(3, 101, 707, 297);
MyTableModel tm=new MyTableModel(l);
table = new MyTable(tm);
table.setBorder(new EmptyBorder(0, 0, 0, 0));
table.setOpaque(false);
//table.getTableHeader().setBackground(new Color(0,0,0,0));
table.getTableHeader().setOpaque(true);
table.getTableHeader().setBorder(new EmptyBorder(0,0,0,0));
table.setBackground(new Color(0,0,0,0));
table.setFont(new Font("Segoe UI Semibold", Font.PLAIN, 12));
table.setFillsViewportHeight(false);
table.getTableHeader().setFont(new Font("Segoe UI Semibold", Font.PLAIN, 13));
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
pane.setViewportView(table);
pane.getViewport().setOpaque(false);
table.setGridColor(Color.GRAY);
table.setShowGrid(true);
getContentPane().add(pane);
MyTuple, MyTable and MyTableModel classes don't set any custom rendering.
This is how my table looks like under System L&F (which I really like):
This is how my table looks like under Nimbus L&F (note the added big rectangle):
I want my table to look like the one with System L&F.
The problem is that if I set one L&F like I want, the other gets ugly, I want a sort of "compatibility", is there a way to do so?
Maybe using the UIManager.put() method?
You forgot to set the border around the viewport of the scrollpane. Possible solutions:
pane.setViewportBorder(null);
pane.setViewportBorder(BorderFactory.createEmptyBorder());
pane.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
Note that pane.getViewport().setBorder(...) will not work, because a JViewport doesn't actually have a border, setViewportBorder just draws a border around the viewport. (Reference)
To make the table header transparent:
pane.setColumnHeader(new JViewport());
pane.getColumnHeader().setOpaque(false);
table.getTableHeader().setOpaque(false);

Get error in Swing java - IllegalArgumentException

Tried to put on frame some swing components.
This code worked to days ago. Now it's not work, didn't nothing.
Maybe somebody can tell me what it's wrong?
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setSize(500, 400); //Size of frame
mainFrame.setTitle("Cinema City"); //Set title
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel mainLabel = new JLabel("Welcome to Cinema City catalog!");
JLabel actorLabel = new JLabel("Actors: ");
JLabel laLabel = new JLabel("Last added: ");
JLabel searchLabel = new JLabel("How to search ?");
GridBagConstraints gbc = new GridBagConstraints();
mainFrame.add(mainLabel, new GridBagConstraints(4, 0, 1, 3, 1, 1,
GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
new Insets(20, 160, 0, 0), 0, 0));
mainFrame.add(actorLabel, new GridBagConstraints(0, 0, 1, 1, 1, 1,
GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
new Insets(100, 0, 0, 0), 0, 0));
mainFrame.setVisible(true);
This is the error:
Exception in thread "main" java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
at java.awt.BorderLayout.addLayoutComponent(Unknown Source)
at javax.swing.JRootPane$1.addLayoutComponent(Unknown Source)
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at javax.swing.JFrame.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at GUI.main(GUI.java:40)
You're not actually setting your layout to GridBagLayout, so it is still the default (which would be a FlowLayout).
Of course, only a GridBagLayout can actually handle GridBagConstraints.
This can be fixed by changing your declaration to JFrame mainFrame = new JFrame(new GridBagLayout());
Layout is not mentioned for the particular JFrame - mainframe
Add this line after the JFrame declaration
mainFrame.setLayout(new GridBagLayout());
Should work fine.
you are not set frame layout .
after creation object of frame write this code.
new GridBagLayout();
mainFrame.setLayout(gbl);
its work

Java: Can't apply Gridlayout to a Jscrollpane. Get Get java.lang.ClassCastException

I use a Gridlayout to place 4 elements in one Line. First I had a JPanel and everything worked fine. For the case that the number of lines get to big and I have to be able to scroll down, I changed it a bit. Now I have my JPanel with one JScrollPane added on it. I used the same code, now I just add the elements to the viewport of the Jscrollpane, but now I get this exception Get java.lang.ClassCastException: layout of JScrollPane must be a ScrollPaneLayout: at javax.swing.JScrollPane.setLayout(Unknown Source) and I dont know exactly why. Why shouldnt be Gridlayout's be unknown for Jscrollpane?
Here is the code:
public objectDetails() {
setTitle("LLI_MC_Solver");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setLayout(new GridLayout());
setBounds(100, 100, 510, 401);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setVisible(true);
contentPane.setPreferredSize(new Dimension(500, 390));
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setViewportBorder(new LineBorder(new Color(0, 0, 0), 2));
scrollPane.setBounds(10, 10, 474, 342);
scrollPane.setLayout(new GridLayout(0,4)); //Line which causes the error
scrollPane.setPreferredSize(new Dimension(465, 330));
contentPane.add(scrollPane);
JPanel view = (JPanel)scrollPane.getViewport().getView();
for(Values v : colDetails)
{
JLabel lblC = new JLabel();
lblC.setText(k);
view.add(lblC);
view.validate();
JLabel lblN = new JLabel();
lblN.setText(v.getName());
view.add(lblN);
view.validate();
JLabel lblT = new JLabel();
lblT.setText(v.getType());
view.add(lblT);
view.validate();
JTextField valueBox = new JTextField();
valueBox.setText(v.getValue());
view.add(valueBox);
view.validate();
}
}
I marked the line which causes the Problem according to the compiler. I dont understand why, with the JPanel the same code worked fine. The for-loop where the elements are added I posted for completion purposes, the issue must be somewhere in the setLayout()-Method.
Thanks in advance, appreciate every help.
scrollPane.setLayout(new GridLayout(0,4)); //Line which causes the error
You can't change the layout manager of a scrollpane.
A JScrollPane has its own custom layout manager because it needs to manage the horizontal/vertical scrollbars as well as the row/column headers etc..
Instead you add a panel that uses a GridLayout:
JPanel panel = new JPanel( new GridLayout(0, 4) );
panel.add( component1 );
panel.add( component2 );
panel.add( component3 );
panel.add( component4 );
JScrollPane = new JScrollPane( panel );

Categories