I'm tried to add a JPanel to a JScrollPane using:
panel1 Panel1 = new panel1();
jScrollPane1.setViewportView(Panel1);
and it worked. But the problem is scrollPane doesn't show scroll bars even the Panel1 is bigger. (I'm working with NetBeans & panel1 is a jpanel form)
Override, getPreferredSize() method for the said JScrollPane, you might be able to see the Scroll Bar. Or one can simply call setPreferredSize(), though as stated in the API
Sets the preferred size of this component. If preferredSize is null, the UI will be asked for the preferred size
overriding will be beneficial, as it tends to define some appropriate dimensions to the said JComponent.
Something like this:
JScrollPane scroller = new JScrollPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
};
scroller.setViewportView(panelWithScroll);
One example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PanelScroller {
private void displayGUI() {
JFrame frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
JPanel panelWithScroll = new JPanel();
panelWithScroll.setLayout(new GridLayout(0, 1, 5, 5));
JScrollPane scroller = new JScrollPane() {
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
};
scroller.setViewportView(panelWithScroll);
//scroller.setPreferredSize(new Dimension(300, 200));
for (int i = 0; i < 20; i++) {
panelWithScroll.add(new JLabel(Integer.toString(i + 1), JLabel.CENTER));
}
contentPane.add(scroller);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new PanelScroller().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
If you only want the scrollbars to show up you can call
JScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
JScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
But that don't make them work at all.
if you wont to make them work you can try to set the preferred size of the component inside the Scrollpane to larger then size of Scrollpane and then call repaint(e.g. by make the window fullscreen)
Related
I can't figure out why this code doesn't make scrollbars appear. I'm a complete beginner at Swing so the scrollpanes are very confusing and I don't understand some of the solutions I have seen online. The annoying thing is this code briefly worked but I destroyed the successful part before backing it up when trying to add a component. Any help would be appreciated!
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame
{
private JPanel leftPanel;
private JButton myButton;
private JPanel scrollPanel;
private JScrollPane scrollPane;
public static void main(String[] args)
{
System.setProperty("swing.defaultlaf", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run() {
new Test();
}
});
}
/**
* Constructor for objects of class Backup
*/
public Test()
{
this.setTitle("testy");
this.setSize(new Dimension(1280,622));
leftPanel = new JPanel();
leftPanel.setBackground(new Color(255,0,0));
leftPanel.setBounds(0, 100, 640, 558);
leftPanel.setEnabled(true);
this.add(leftPanel);
scrollPanel = new JPanel(null);
scrollPanel.setBackground(new Color(100,100,100));
scrollPanel.setPreferredSize(new Dimension(640, 550));
scrollPanel.setEnabled(true);
JScrollPane scrollPane = new JScrollPane(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(0, 0, 642, 550);
scrollPane.setEnabled(true);
leftPanel.add(scrollPane);
for (int i = 1; i < 30; i++)
{
scrollPanel.setLayout(new GridLayout(30, 1, 0, 1));
myButton = new JButton("AAAAAAAAAAAAAAAAAAAAA " + i);
myButton.setPreferredSize(new Dimension(630, 70));
scrollPanel.add(myButton);
}
this.setBackground(new Color(0,0,0));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
}
I think I've massively improved it since then thanks to camickr
Here is the current version:
import javax.swing.*;
import java.awt.*;
public class Test extends JFrame
{
private JPanel leftPanel;
private JButton myButton;
private JPanel scrollPanel;
private JScrollPane scrollPane;
public static void main(String[] args)
{
System.setProperty("swing.defaultlaf",
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run() {
new Test();
}
});
}
public Test()
{
this.setTitle("testy");
this.setSize(new Dimension(1280,622));
leftPanel = new JPanel();
leftPanel.setBackground(new Color(255,0,0));
leftPanel.setBounds(0, 100, 640, 558);
this.add(leftPanel);
scrollPanel = new JPanel();
scrollPanel.setLayout(new GridLayout(70, 1, 0, 1));
//scrollPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20,
20));
scrollPanel.setBackground(new Color(100,100,100));
//scrollPanel.setPreferredSize(new Dimension(640, 550));
//JScrollPane scrollPane = new JScrollPane(scrollPanel);
JScrollPane scrollPane = new JScrollPane(scrollPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//scrollPane.setLayout(new GridLayout(30, 1, 0, 1));
//scrollPane.setBounds(0, 0, 642, 550);
scrollPane.setEnabled(true);
//scrollPanel.add(scrollPane);
leftPanel.add(scrollPanel);
for (int i = 1; i < 71; i++)
{
myButton = new JButton("AAAAAAAAAAAAAAAAAAAAA " + i);
//myButton.setPreferredSize(new Dimension(640, 80));
scrollPanel.add(myButton);
}
this.setBackground(new Color(0,0,0));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}}
Don't use a null layout.
Don't use setBounds().
Don't use setPreferredSize().
Each Swing component is responsible for determining its own preferred size. The layout manager will then set the size/location of each components added to the panel and it will then (dynamically) calculated the preferred size of the panel. The scroll bars will appear when the preferred size of the panel is greater than the size of the scroll pane.
scrollPanel = new JPanel(null);
scrollPanel.setBackground(new Color(100,100,100));
// scrollPanel.setPreferredSize(new Dimension(640, 550)); // delete
//scrollPanel.setEnabled(true); // not needed
...
for (int i = 1; i < 30; i++)
{
//scrollPanel.setLayout(new GridLayout(30, 1, 0, 1)); // set layout when panel created.
//myButton.setPreferredSize(new Dimension(630, 70)); // not needed.
The layout manager should be set outside the loop, when you create the panel. It should NOT be null.
Don't hard code the preferred size. It will not dynamically adjust as components are added.
Swing components are enabled by default to setEnabled is not needed.
Don't use the "leftPanel". Just add the scroll pane directly to the frame. This will allow the scrollpane to resize dynamically as the frame is resized. Then the scroll bars will appear when requirement.
Don't set the preferreid size of the button. The size will be determined based on the text and the Font of the button.
There is a specific UI that I am trying to create for a Java program and I have been having trouble choosing the adequate Layout Managers. I would like my program to have a top panel with three elements (Two JTextFields and one JButton) and a lower JPanel that has another JPanel inside. The inner panel should always be a square, centered according to its container and adapt to the maximum height or width of its container. I have tried using a ComponentAdapter to achieve the effect of always staying a square, but the program does not seem to act the way I want it to, also the top Panel seems to get squeezed to the top
JPanel maincontainer = new JPanel();
maincontainer.setLayout(new BoxLayout(maincontainer, BoxLayout.PAGE_AXIS));
JPanel jpanel2 = new JPanel();
jpanel2.setLayout(new GridLayout(0, 3));
JTextField txt = new JTextField();
txt.setFocusable(false);
JButton btn = new JButton();
btn.setFocusable(false);
JTextField txt2 = new JTextField();
txt2.setFocusable(false);
jpanel2.add(txt);
jpanel2.add(btn);
jpanel2.add(txt2);
maincontainer.add(jpanel2);
JPanel masterPane = new JPanel(new GridBagLayout());
JPanel centerPane = new JPanel();
masterPane.add(centerPane);
masterPane.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
if(masterPane.getHeight()<masterPane.getWidth())
centerPane.setSize(masterPane.getHeight(), masterPane.getHeight());
else
centerPane.setSize(masterPane.getWidth(), masterPane.getWidth());
}
});
centerPane.setBackground(Color.blue);
masterPane.add(centerPane);
maincontainer.add(masterPane);
JFrame frame = new JFrame("");
frame.getContentPane().add(maincontainer);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setMinimumSize(new Dimension(300,300));
frame.setSize(500, 500);
I would like my program to have a top panel with three elements (Two JTextFields and one JButton) and a lower JPanel that has another JPanel inside.
The easiest way to do this is to keep using the default layout manager of the frame which is a BorderLayout. You add the panel with the text fields and buttons to the BorderLayout.PAGE_START. Then you add the panel that changes dynamically to the BorderLayout.CENTER.
The inner panel should always be a square, centered according to its container and adapt to the maximum height or width of its container
The easiest way to center a component on a panel is to use a GridBagLayout on the panel. The default GridBagConstraints will cause the component to be displayed at it preferred size centered both vertically and horizontally. So you will need a wrapper panel using the GridBagLayout to contain your center panel.
You would then want to override the getPreferredSize() method of your center panel to dynamically change as the size of the parent panel changes. This is a better approach than using a ComponentListener.
Something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class SSCCE extends JPanel
{
SSCCE()
{
setLayout( new BorderLayout() );
JPanel top = new JPanel( new GridLayout(0, 3) );
top.add( new JTextField(10) );
top.add( new JButton("Button") );
top.add( new JTextField(10) );
add(top, BorderLayout.PAGE_START);
JPanel center = new JPanel()
{
#Override
public Dimension getPreferredSize()
{
Dimension parent = getParent().getSize();
if (parent.width < parent.height)
return new Dimension(parent.width, parent.width);
else
return new Dimension(parent.height, parent.height);
}
};
center.setBackground( Color.BLUE );
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(center, new GridBagConstraints());
add(wrapper, BorderLayout.CENTER);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
static class DragListener extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me)
{
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
}
In my software i have a JPanel containing some JComponent. The JPanel use a FlowLayout with a certain Hgap to separate these components.
I'm trying to have this kind of design, but the first component should be layed out on left, without any Hgap. Like This:
here is the code you can use to generate the example:
public class FlowLayoutExample {
public static void main(String [] a) {
final JFrame frame = new JFrame();
frame.setSize(new Dimension(500, 80));
frame.setMinimumSize(new Dimension(350, 80));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(initJPanel());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});
}
private static JPanel initJPanel() {
JPanel panel = new JPanel();
FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT);
flowLayout.setHgap(25);
panel.setLayout(flowLayout);
panel.setBackground(Color.LIGHT_GRAY);
panel.add(initLabel());
panel.add(initLabel());
panel.add(initLabel());
panel.add(initLabel());
return panel;
}
private static Component initLabel() {
return new JLabel("MyLabel");
}
}
Thanks for any suggestion you'll leave !
You can use an EmptyBorder to fake it out:
panel.setBorder( new EmptyBorder(0, -25, 0, 0) );
Basically the border inset and layout gap are added together.
I am working on the editor. I am using Java swing for it. I have embedded a JTextArea with JScrollPane. i want to position the jtextarea of particular size at the middle of JScrollPane. To do this I used setLocation function. But this is not working?
public class ScrollPaneTest extends JFrame {
private Container myCP;
private JTextArea resultsTA;
private JScrollPane scrollPane;
private JPanel jpanel;
public ScrollPaneTest() {
resultsTA = new JTextArea(50,50);
resultsTA.setLocation(100,100);
jpanel=new JPanel(new BorderLayout());
jpanel.add(resultsTA,BorderLayout.CENTER);
scrollPane = new JScrollPane(jpanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(800, 800));
scrollPane.setBounds(0, 0, 800, 800);
setSize(800, 800);
setLocation(0, 0);
myCP = this.getContentPane();
myCP.setLayout(new BorderLayout());
myCP.add(scrollPane);
setVisible(true);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) {
new ScrollPaneTest();
}
}
You simply have to add the JTextArea to the JScrollPane, and add it to the CENTER of the JPanel having BorderLayout.
Don't use AbsolutePositioning. Add a proper LayoutManager, and let LayoutManager do the rest for positioning and sizing your components on the screen.
In order to use the setBounds(...) method you have to use a null Layout for your component, which is not worth using, provided the perspective, as mentioned in the first paragraph of the AbsolutePositioning. Though in the code example provided by you, you are doing both the thingies together i.e. using Layout and using AbsolutePositioning, which is wrong in every way. My advice STOP DOING IT :-)
In the example provided the ROWS and COLUMNS provided by you are sufficient to size the JTextArea by the Layout concern.
Code Example :
import java.awt.*;
import javax.swing.*;
public class Example
{
private JTextArea tarea;
private void displayGUI()
{
JFrame frame = new JFrame("JScrollPane Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JScrollPane textScroller = new JScrollPane();
tarea = new JTextArea(30, 30);
textScroller.setViewportView(tarea);
contentPane.add(textScroller);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new Example().displayGUI();
}
});
}
}
For some reason i am having problems centering my panel vertically that is located inside another panel. I do exactly as the examples i studied but still no luck.
Down there is my code. Despite using setAlignmentY(0.5f) on my container panel, it still wont center when i resize the window.
Also the components inside container panel wont center either, despite setAligenmentX(0.5f).
I wonder if there is a solution for this, I pretty much tried everything out there but couldnt find a solution.
JLabel idLabel;
JLabel passLabel;
JTextField id;
JTextField pass;
JButton enter;
JPanel container;
public JournalLogin()
{
//setLayout(new FlowLayout());
//setPreferredSize(new Dimension(500, 500));
//setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
container = new JPanel();
container.setLayout(new MigLayout());
container.setAlignmentX(0.5f);
container.setAlignmentY(0.5f);
container.setPreferredSize(new Dimension(300, 300));
container.setBorder(BorderFactory.createTitledBorder("Login"));
add(container);
idLabel = new JLabel("ID:");
idLabel.setAlignmentX(0.5f);
container.add(idLabel);
id = new JTextField();
id.setText("id");
id.setAlignmentX(0.5f);
id.setPreferredSize(new Dimension(80, 20));
container.add(id, "wrap");
setAlignmentX and Y are not the way to go about doing this. One way to center a component in a container is to have the container use GridBagLayout and to add the component without using any GridBagConstraints, a so-called default addition. There are other ways as well.
For example to alter Nick Rippe's example (1+ to him):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
public class UpdatePane2 extends JPanel {
private static final int PREF_W = 300;
private static final int PREF_H = 200;
public UpdatePane2() {
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BorderLayout());
innerPanel.add(new JLabel("Hi Mom", SwingConstants.CENTER),
BorderLayout.NORTH);
innerPanel.add(new JButton("Click Me"), BorderLayout.CENTER);
setLayout(new GridBagLayout());
add(innerPanel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("UpdatePane2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new UpdatePane2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Alignments tend to be pretty picky in Swing - they do [usually] work... but if all you're looking for is a panel that's centered, I'd recommend using Boxes in the BoxLayout (My personal favorite LayoutManager). Here's an example to get you started:
import java.awt.Dimension;
import javax.swing.*;
public class UpdatePane extends JPanel{
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
//Create Buffers
Box verticalBuffer = Box.createVerticalBox();
Box horizontalBuffer = Box.createHorizontalBox();
verticalBuffer.add(Box.createVerticalGlue()); //Top vertical buffer
verticalBuffer.add(horizontalBuffer);
horizontalBuffer.add(Box.createHorizontalGlue()); //Left horizontal buffer
//Add all your content here
Box mainContent = Box.createVerticalBox();
mainContent.add(new JLabel("Hi Mom!"));
mainContent.add(new JButton("Click me"));
horizontalBuffer.add(mainContent);
horizontalBuffer.add(Box.createHorizontalGlue()); //Right horizontal buffer
verticalBuffer.add(Box.createVerticalGlue()); //Bottom vertical buffer
// Other stuff for making the GUI
verticalBuffer.setPreferredSize(new Dimension(300,200));
JFrame frame = new JFrame();
frame.add(verticalBuffer);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
You will need to get the LayoutManager to center the layout for you. Currently it looks like the implementation of "MigLayout" does not honor the Alignment. Try changing it or creating a subclass.