I am using NetBeans. I turned off the auto-resize of JTable columns. Now it is aligned to the left side of scroll pane. How can I make it centered?
Found the solution. Have to add an extra panel.
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(500, 400);
JButton button = new JButton("Click me");
button.setPreferredSize(new Dimension(200, 40));
JPanel panel = new JPanel();
panel.add(button);
JScrollPane scrollableArea = new JScrollPane(panel);
frame.add(scrollableArea);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Really a great and unexpected solution. Sometime java really acts weird. Here is the orginal post http://www.velocityreviews.com/forums/t600361-jscrollpane.html
Related
I try to program a GUI like this. When a button clicked every time a new button is created and placed at specific position but after adding some buttons in jscrollpane, scrollbar not activated, so I unable to see all created buttons.
My code is here:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test{
private JFrame frame;
private JPanel panel1,panel2;
private JScrollPane pane;
private JButton button;
int i = 1, y = 10;
public Test()
{
panel2 = new JPanel(null);
panel2.setBounds(0,0,280,300);
button = new JButton("Add Button");
button.setBounds(90,10,120,30);
pane = new JScrollPane();
pane.setBounds(10,50,280,300);
panel1 = new JPanel(null);
panel1.setPreferredSize(new Dimension(300,400));
panel1.setBackground(Color.WHITE);
frame = new JFrame("Test");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel1);
frame.pack();
panel1.add(pane);
panel1.add(button);
pane.add(panel2);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel2.add(new JButton("Button "+i)).setBounds(80,y,120,30);
i += 1;
y += 35;
}
});
}
public static void main(String[] args) {
new Test();
}
}
Don't use a null layout. Don't use setBounds().
The scrollbars will only appear automatically when the preferred size of the panel is greater that the size of the scroll pane.
It is the job of the layout manager to:
set the location of a component
set the size of a component
calculate the preferred size of the panel.
So the solution is to use the appropriate layout manager on your panel.
So for example you can use a BoxLayout:
//panel2 = new JPanel(null);
panel2 = new JPanel();
panel2.setLayout( new BoxLayout(panel2, BoxLayout.Y_AXIS) );
And then when you add components to a visible frame you need to revalidate() the panel to invoke the layout manager:
//panel2.add(new JButton("Button "+i)).setBounds(80,y,120,30);
panel2.add(new JButton("Button "+i));
panel2.revalidate();
There is no need for panel1. Just add the components to the frame:
//panel1.add(pane);
//panel1.add(button);
frame.add(button, BorderLayout.PAGE_START);
frame.add(pane, BorderLayout.CENTER);
But there are other issues:
pane = new JScrollPane();
You actually need to add the panel to the scroll pane. So the code should be:
pane = new JScrollPane(panel2);
Since a component can only have a single parent, you need to remove:
pane.add(panel2);
Since the panel2 has been added to the scroll pane.
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel1);
frame.pack();
The above logic is wrong.
You should only invoked pack() and setVisible( true ) AFTER all the component have been added to the frame.
So most of the code posted is wrong.
Start by reading the section from the Swing turtorial on Layout Managers. Download the working demo code and learn how to better structure your code. The modify the code for your specific example.
I have a Panel which I have made scrollable in my frame.
What I need is to add a button that stays fixed in the lower right corner even when I scroll.
I'm new to Java Swing so would appreciate all and any help that I can get.
mainPanel = new SimulationPanel(); //class SimulationPanel extends JPanel
//making mainPanel scrollable
mainPanel.setPreferredSize(new Dimension(((int)(WIDTH*1.2)), HEIGHT));
JScrollPane scrollPane = new JScrollPane(mainPanel);
scrollPane.setViewportView(mainPanel);
// Settings for JFrame
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame = new JFrame("Warehouse Simulator");
frame.setContentPane(scrollPane);
frame.setSize(screenSize.width, screenSize.height);
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
I would use nested panels with the outer one be with BorderLayout. Then one with FlowLayout and align FlowLayout.RIGHT and the button inside it.
public class Example extends JFrame {
public Example() {
super("");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JTextArea textArea = new JTextArea(10000, 0);
JScrollPane scrollPane = new JScrollPane(textArea);
add(scrollPane, BorderLayout.CENTER);
JButton button = new JButton("button");
JPanel panelWithButton = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panelWithButton.add(button);
add(panelWithButton, BorderLayout.PAGE_END);
setLocationByPlatform(true);
pack();
setSize(600, 600);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Example().setVisible(true);
});
}
}
Result:
I would go for a BoxLayout. Add another panel (metaPanel) in which your first put your scrollingPanel, and then you add a button. Instead of usgin scrollingPanel as contentPane, you use metaPanel. Example (the example works, but you need to modify it to make the interface look nice):
JPanel mainPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(mainPanel);
scrollPane.setViewportView(mainPanel);
JPanel metaPanel = new JPanel();
BoxLayout boxlayout = new BoxLayout(metaPanel, BoxLayout.Y_AXIS);
metaPanel.setLayout(boxlayout);
metaPanel.add(scrollPane);
metaPanel.add(new JButton("button"));
// Settings for JFrame
frame = new JFrame("Warehouse Simulator");
frame.setContentPane(metaPanel); // Put metaPanel here
frame.setSize(500, 300);
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
I have created a JScrollPane with a RowHeaderView, a ColumnHeaderView and a ViewPortView. I added JPanels in diffrent colors and noticed, that there is one cornor left, on the upper-left where you cant just add a Component. I wanted to ask, how it is possible to add a Component there.
Here a image. The area I mean is green:
And here my Code:
public class Example {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(1000, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JPanel panel0 = new JPanel();
panel0.setBackground(Color.yellow);
JPanel panel1 = new JPanel();
panel1.setBackground(Color.red);
panel1.setPreferredSize(new Dimension(30, 200));
JPanel panel2 = new JPanel();
panel2.setBackground(Color.blue);
panel2.setPreferredSize(new Dimension(200, 30));
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(panel0);
scrollPane.setRowHeaderView(panel1);
scrollPane.setColumnHeaderView(panel2);
scrollPane.setBackground(Color.green);
frame.add(scrollPane);
frame.setVisible(true);
}
}
It's easy. Use the method setCorner
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, new JButton());
I want to change the color of JButton by:
JButton button = new JButton();
button.setBackground(Color.decode("#00a5ff"));
In order for change to occur, I have to add:
button.setOpaque(true);
button.setBorderPainted(false);
However, this remove the curves around the edges and thus changes the shape of the button. Is there a way to just simply change to color and keep the other properties? Another example is the changing of color (getting darker) when you press a button without having changed its color.
Here is some code that illustrates the difference between the two buttons:
public static void main(String[] args) {
JFrame frame = new JFrame("frame");
frame.setSize(new Dimension(300, 300));
JButton button1 = new JButton();
JButton button2 = new JButton();
button1.setPreferredSize(new Dimension(100,100));
button2.setPreferredSize(new Dimension(100,100));
button2.setBackground(Color.decode("#00a5ff"));
button2.setBorderPainted(false);
button2.setOpaque(true);
JPanel pane1 = new JPanel(new FlowLayout());
JPanel pane2 = new JPanel(new FlowLayout());
pane1.add(button1);
pane2.add(button2);
frame.add(pane1, BorderLayout.WEST);
frame.add(pane2, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
Thanks
I literally just tested the following:
JFrame frame = new JFrame("frame");
frame.setSize(new Dimension(300, 300));
JButton button = new JButton();
button.setBackground(Color.decode("#00a5ff"));
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
It seemed to work, but I am working on Ubuntu Studio 16.04. If you notice that it does not work, then let me know. Could you please show the result of your white button or your failed button (if it still doesn't work)?
Perhaps you have something else going on in your code. I altered a small example I have and the color changes with only setBackground(Color) using regular Button and using JButton. See the following...
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel();
Button closeButton = new Button("Close");
closeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
frame.dispose();
}
});
closeButton.setBackground(Color.decode("#00a5ff"));
panel.add(closeButton);
frame.add(panel);
frame.setSize(200, 100);
frame.setLocation(200, 50);
frame.setVisible(true);
}
Since im a beginner and i don't want to get involved with the layout managers, i was simply adding a JPanel into my main JFrame and giving spesific location to each component in the panel. But somehow the output appears way too wrong..
frame = new JFrame(email + " (Offline)");
frame.setSize(400, 400);
frame.setLocation(0, 0);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
// out.println("BYE");
// out.flush();
frame.dispose();
thread.stop();
}
});
panel = new JPanel();
frame.add(panel);
chat = new JTextArea();
chat.setSize(400, 200);
chat.setLocation(0, 0);
chat.setEditable(false);
panel.add(chat);
panel.validate();
JLabel you = new JLabel("You:");
you.setSize(you.getPreferredSize());
you.setLocation(0, 210);
panel.add(you);
panel.validate();
input = new JTextArea();
input.setSize(200, 200);
input.setLocation(0, 220 + chat.getSize().height);
panel.add(input);
panel.validate();
send = new JButton("Send");
send.setSize(send.getPreferredSize());
send.setLocation(210, 220 + chat.getSize().height);
panel.add(send);
panel.validate();
frame.setVisible(true);
The outcome of this frame is that text areas are invisible, a You: label in the middle and next to the right of it the button.. What am i missing here?
Again, don't use null layout since it makes updating and maintaining your GUI much more difficult than it should be, and can lead to ugly GUI's if you plan on having them run on multiple platforms. Instead
Use several JPanels, each one holding a core group of components and each using its best layout manager
Nest these JPanels in other JPanels that use the best layout manager to display them
and that will allow your GUI to be resizeable without need of extra code.
Put your JTextAreas in JScrollPanes so that you can see all text even if it goes beyond the text area.
Never set the size of the JTextArea as that will not allow it to scroll. Instead set its columns and rows.
As a very simple example, run this to see what I mean:
import java.awt.*;
import javax.swing.*;
public class FooSwing2 {
public static void main(String[] args) {
JTextArea chatArea = new JTextArea(8, 40);
chatArea.setEditable(false);
chatArea.setFocusable(false);
JScrollPane chatScroll = new JScrollPane(chatArea);
JPanel chatPanel = new JPanel(new BorderLayout());
chatPanel.add(new JLabel("Chat:", SwingConstants.LEFT), BorderLayout.PAGE_START);
chatPanel.add(chatScroll);
JTextField inputField = new JTextField(40);
JButton sendBtn = new JButton("Send");
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.LINE_AXIS));
inputPanel.add(inputField);
inputPanel.add(sendBtn);
JPanel youLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
youLabelPanel.add(new JLabel("You:"));
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
mainPanel.add(chatPanel);
mainPanel.add(Box.createVerticalStrut(10));
mainPanel.add(youLabelPanel);
mainPanel.add(inputPanel);
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
This would result in a simple (non-functioning) GUI that looked like this:
Now say you want to change this and add another button, an "exit" JButton to the right of the send JButton. If you used null layout, you'd have to resize your GUI, you'd have to move the send button over to the left and make sure that your math was without error, etc. If you used layout managers, you'd need just two new lines of code (to change the display, not the functionality of course):
JTextField inputField = new JTextField(40);
JButton sendBtn = new JButton("Send");
JButton exitBtn = new JButton("Exit"); // ***** added
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.LINE_AXIS));
inputPanel.add(inputField);
inputPanel.add(sendBtn);
inputPanel.add(exitBtn); // ***** added
That's it, and this would display: