I have a JScrollPane and JPanel inside it(I want to draw on JPanel). Also I have a method that draws lines with parametre of length of the line. I want my JScrollPane to scroll if the length of the line is more then the size(height or width) of my JPanel that is on JScrollPane.
How can I do this?
P.S. I've tried jScrollPane.scrollRectToVisible but it doesn't work
Here is an example implementing what you want
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class DrawLine {
JFrame j;
JPanel p;
JScrollPane sp;
public DrawLine() {
j = new JFrame();
p = new JPanel() {
public void paintComponent(Graphics g) {
g.drawLine(20, 20, 250, 250);
}
};
p.setPreferredSize(new Dimension(300, 300));
sp = new JScrollPane(p);
j.getContentPane().add(sp);
j.setSize(300, 300);
j.setVisible(true);
}
public static void main(String[] args) {
new DrawLine();
}
}
Note the line p.setPreferredSize(new Dimension(300, 300)); which sets the preferred size of the panel.
You need to define the following method in the LinePanel class:
public Dimension getPreferredSize() {
return new Dimension(myLine.getWidth(), myLine.getHeight());
}
Make sure that myLine object is available to the above method. And, you will get the scrollbars as needed.
P.S.: I assume LinePanel extends JPanel and is the panel on which the line is drawn.
You need to associate the JScrollPanel with the JPanel that it is scrolling. That is, you need
JScrollPane lineScrollPane = new JScrollPane(linePanel);
This will create a JScrollPane that automatically sizes itself to scroll over whatever linePanel's size is.
It's important to make sure then, that the panel containing your line actually IS big enough to fit entire line. That is, you might have something like
linePanel.setSize(myLine.getWidth(), myLine.getHeight());
or whatever your associated line size is. Note that something like
lineScrollPanel.setSize(new Dimension(600, 400));
will resize the scroll panel but not the thing inside--that is, it will be a 600x400 scroll pane but the inside panel may be bigger smaller, and it will be scrolled.
Related
I'm trying to add the JScrollPane to my JTextArea, but somehow, it won't appear.
I've tried resizing it according to the dimension of the JTextArea, but it doesn't seem to work. Also, notice that I'm using the null layout because I want the full-on flexibility of displaying certain buttons and panels at a pinpoint location.
import java.awt.Dimension;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.JTextArea;
public class PaneTester{
private static JFrame frame;
private static JPanel panel;
private static JScrollPane scrollPane;
private static JTextArea notificationBox;
public static void main (String [] args){
stage1();
stage2();
}
private static void stage1(){
createFrame();
createPanel();
frame.getContentPane().add(panel);
panel.setVisible(true);
frame.setVisible(true);
}
private static void stage2(){
generateNotificationBox();
}
private static void createFrame(){
frame = new JFrame();
frame.setSize(new Dimension(900,700));
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
}
private static void createPanel(){
panel = new JPanel();
panel.setLayout(null);
generateGridButtons();
}
private static void generateGridButtons(){
short y = 0;
for(short i=0;i<4;i++){
y += 60;
short x = 500;
for(short j=0;j<5;j++){
JButton gridButton = new JButton();
gridButton.setBounds(x, y,120,60);
panel.add(gridButton);
x += 140;
}
}
}
public static void generateNotificationBox(){
notificationBox = new JTextArea(10,10);
notificationBox.setBounds(25, 25, 200, 400);
scrollPane = new JScrollPane(notificationBox, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS );
Dimension d = new Dimension(notificationBox.getPreferredSize());
scrollPane.getViewport().setPreferredSize(d);
scrollPane.getViewport().add(notificationBox);
panel.add(notificationBox);
panel.repaint();
}
}
Stop mucking with setBounds and setPreferredSize, you're just making live more difficult for your self.
If you want to affect the size of JTextArea (and the viewable area of the JScrollPane) have a look at the JTextArea constructor JTextArea(int rows, int columns), which will allow you to specify the number of rows/columns you want the JTextArea to default to, and which will allow the JTextArea to calculate it's preferredSize based on the current font's metrics in more stable cross platform way
Your core problem, however, is right here...
scrollPane.getViewport().add(notificationBox);
panel.add(notificationBox);
You add the notificationBox to the JScrollPanes JViewport, which is good, but then you add notificationBox to the panel, which will remove it from the JScrollPane's JViewport, which is bad
Instead, add the JScrollPane to the panel
scrollPane.getViewport().add(notificationBox);
panel.add(scrollPane);
You're also making overuse of static. I'd highly recommend you take the time to reduce static down to it's absolute minimum required usage, this will probably mean that rather then constructing the UI in the main method, you have a "main" class which you can insatiate (from main) which will perform the initial setup - IMHO
I've tried that. I think someone else suggested that from another post, but when I tried that, it just took away the JTextArea completely from the panel
Get rid of panel.setLayout(null); and start making use of appropriate layout managers and compound layouts. Start by having look at Laying Out Components Within a Container for more details
I want to use two JPanels in one JFrame, with an invisible horizontal line between them. I played a little bit and got this:
public class Application {
public static void main(String[] args)
{
JFrame jframe = new JFrame();
jframe.setSize(500,700);
jframe.setVisible(true);
jframe.setTitle("Title");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setResizable(false);
JSplitPane splitPane = new JSplitPane();
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setDividerLocation(250);
splitPane.setLeftComponent(leftPanel);
splitPane.setRightComponent(rightPanel);
jframe.add(splitPane);
}
}
Now, the first problem is how can I turn off the "resizability" of the Line between the panels? And how do I make it "invisible"? Maybe use something else than split pane?
Second of all, how do can I work with only one side of the JPanel?
(I am working on an application that lets you draw a circle on the left hand side).
This seems like an easy question but I am relatively new to Java.
As said before in a comment by #MadProgrammer you can use BorderLayout or GridBagLayout but as you're placing the "split" line right in the middle of both panels you could use GridLayout which will make both panels be of the same size no matter if the window is resized.
I didn't tried with GridBagLayout but I did an example on how you could achieve this pane separation without using a JSplitPane.
With GridLayout all you need to do is add the elements to the left pane (in my example I used a JLabel to differentiate them) while in BorderLayout you need to specify that the panel where you'll be painting the circle to be aligned to the left (WEST constant) as I did.
However if you use BorderLayout approach and add text or elements to the right pane, they will be aligned to the right, you can fix it by "boxing" the elements in another pane with a different Layout.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Application {
private JFrame frame;
private JPanel containerPane;
private JPanel topPane;
private JPanel bottomPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Application().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("Example of 2 panels");
containerPane = new JPanel();
topPane = new JPanel();
bottomPane = new JPanel();
containerPane.setLayout(new GridLayout(2, 1));
topPane.setLayout(new GridLayout(1, 2));
bottomPane.setLayout(new BorderLayout());
topPane.add(new JLabel("Left side"));
topPane.add(new JLabel("Right side"));
bottomPane.add(new JLabel("Left side"), BorderLayout.WEST);
bottomPane.add(new JLabel("Right side"), BorderLayout.EAST);
topPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLUE), "Using GridLayout"));
bottomPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLUE), "Using BorderLayout"));
containerPane.add(topPane);
containerPane.add(bottomPane);
frame.add(containerPane);
// frame.pack();
frame.setSize(500, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I didn't call pack() in this example because the size of both panels (or JLabels in this case was not tall enough to show the difference:
Using pack():
Calling setSize():
Additional tips
Don't forget to place your program on the Event Dispatch Thread (EDT), I did it by writing these lines on the main method:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Application().createAndShowGui();
}
});
Don't place all your code on the constructor, otherwise it will be hard to maintain
It looks like you can use GridLayout to do this. Here is what i think,
public class Application {
public static void main(String[] args) {
JFrame jframe = new JFrame();
jframe.setTitle("Title");
jframe.setResizable(false);
//This creates one row and two equally divided columns
GridLayout gridLayout = new GridLayout(0, 2);
jframe.setLayout(gridLayout);
gridLayout.layoutContainer(jframe);
JPanel leftPanel = new JPanel();
leftPanel.add(new Label("Left side"));
jframe.add(leftPanel);
JPanel rightPanel = new JPanel();
rightPanel.add(new Label("Right side"));
jframe.add(rightPanel);
jframe.setSize(800, 500);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here is how it looks:
The panels will not resize as well as there is no line visible that seprates them.
So I've made a class WindowDisp which extends JFrame:
public class WindowDisp extends JFrame{
private static final long serialVersionUID = 3245091489595286109L;
private int height, width;
private JPanel panel;
private JLabel mainPane;
public WindowDisp(int a, int b, int pw, int ph){
height = a;
width = b;
Container c = getContentPane();
c.setPreferredSize(new Dimension(width, height));
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
mainPane = new JLabel();
mainPane.setPreferredSize(new Dimension(pw, ph));
mainPane.setFont(new Font("Monospaced", Font.PLAIN, 10));
panel = new JPanel();
panel.setPreferredSize(getSize());
panel.add(mainPane);
add(panel);
setVisible(true);
pack();
}
public static void main(String[] args){
WindowDisp win = new WindowDisp(400, 400, 400, 400);
}
}
From my Main class, I declare a WindowDisp where its height and width are equal to its ph and pw. The problem, however, is that, upon running my program, white 'bars' appear around the default background colored JPanel in the frame. They appear to be padding the panel from the right and the bottom, as though there is space in the frame that the panel is not occupying, although, if my coding is correct, the panel should be the same size as the frame's ContentPane, should it not?
I've found that removing either of the two pack(); commands does not remove these bars, although removing the first one changes them to black, and removing the second widens the one on the right. Of course, removing both of them causes the frame not to be the same size as its ContentPane. Furthermore, removing the add(panel); altogether has no effect.
I can't figure out what in this code is causing that seemingly empty space to appear in my frame, and, again, in my program, all four values being passed to the Window constructor are equal. What seems really strange is that, even if I just remove the add(panel);, nothing at all changes visa vi the white padding. In fact, I can comment out everything from mainPane =... to add(panel); and that doesn't affect it at all.
I can't seem to replicate the issue exactly, but I think I can replicate the desired results...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class WindowDisp extends JFrame {
private static final long serialVersionUID = 3245091489595286109L;
private JPanel panel;
private JLabel mainPane;
public WindowDisp(int width, int height) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
mainPane = new JLabel();
mainPane.setBorder(new LineBorder(Color.BLUE));
mainPane.setFont(new Font("Monospaced", Font.PLAIN, 10));
panel = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
};
panel.setLayout(new BorderLayout());
panel.setBorder(new EmptyBorder(4, 4, 4, 4));
panel.add(mainPane);
add(panel);
pack();
setLocationRelativeTo(null);
setVisible(true);
System.out.println(getSize());
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
WindowDisp win = new WindowDisp(400, 400);
}
});
}
}
Things that jump out at me (as been of issue)...
panel.setPreferredSize(getSize()); - The size of the window is generally larger than the window size, this is because the window has decorations which are painted WITHIN the frame boundaries. pack uses the layout information (and preferredSize of the components indirectly) to ensure that the content has the amount of space that it asks for, it then sizes the window around this to accommodate the frame decorations. By calling getContentPane().setPreferredSize you are superseding any information that the layout manager might provide and ignoring the requirements of the other components. This is one of the (many) reasons why we recommend that you NEVER call setPreferredSize, ever...
To reiterate...
Container c = getContentPane();
c.setPreferredSize(new Dimension(width, height));
Forces the viewable space of the window to be set to the width/height values (400x400). This container will no longer be able to react to changes to it's content and will ALWAYS prefer to be 400x400
mainPane.setPreferredSize(new Dimension(pw, ph));
Sets the preferred size of the mainPane to 400x400 (based on your example). Again, it will ALWAYS prefer to be 400x400, but the simple fact of setting the content pane, means that this value is actually ignored...
panel.setPreferredSize(getSize());
Now, the nail in the coffin. This sets the panel to be the same size of the frame, BUT, the frame is larger than the contentPane (400x400 + frame decorations), it is also offset within frame (it won't be positioned at 0x0, but will be offset so that it appears below the frame's title and right border), but could expand beyond the frames boundaries
This combination of issues are all working against you. Instead of worrying about the frame size, worry about the size needs/requirements of the what the frame displays.
Each OS uses different frame decorations, so the actual, physical, frame size will be different on different OSs, but if you focus on the requirements of the content, you won't care
See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes.)
Instead use layout padding and borders for white space. Finally, call pack() to ensure the frame is exactly as large as (the smallest size) it needs to be in order to display the components and white space.
import java.awt.Font;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class WindowDisp extends JFrame {
private JPanel panel;
private JLabel mainLabel;
public WindowDisp(int t, int l, int b, int r, String title) {
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setResizable(false);
setLocationByPlatform(true);
mainLabel = new JLabel("Hello Padding!");
mainLabel.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 10));
mainLabel.setBorder(new EmptyBorder(t, l, b, r));
panel = new JPanel();
panel.add(mainLabel);
add(panel);
pack();
setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new WindowDisp(50, 150, 50, 150, "Window 1");
new WindowDisp(50, 100, 50, 100, "Window 2");
}
};
SwingUtilities.invokeLater(r);
}
}
So far the best patch for this annoying issue is the following. Doesn't matter where you call the setResizable(false) method. Just add this piece of code after you setVisible(true).
private void sizeBugPatch() {
while (frame.getWidth() > yourWidth) {
frame.pack();
}
}
Where yourWidth is the width you've set in any of the possible ways, either manually or by overriding setPreferredSize methods. The explanation is quite easy, frame.pack() seems to reset frame.setResizable(boolean b) somehow. You could use an if instead of the while loop but I prefer while to exclude the case the window would still be extra-sized even after a second pack().
One thing I have learned from swing days is to never mix setPreferred... with pack(). You either use one or the other.
Try this code:
import javax.swing.*;
import java.awt.*;
public class WindowDisp extends JFrame {
private int height, width;
private JPanel panel;
private JLabel mainPane;
public WindowDisp(int a, int b, int pw, int ph){
height = a;
width = b;
Container c = getContentPane();
// c.setPreferredSize(new Dimension(width, height));
mainPane = new JLabel("Hello from Pane");
mainPane.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 10));
panel = new JPanel();
// panel.setPreferredSize(new Dimension(pw, ph));
panel.add(mainPane);
c.add(panel, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
pack();
setVisible(true);
}
public static void main(String[] args){
WindowDisp win = new WindowDisp(400, 400, 400, 400);
}
}
Output:
Don't know if I'm making a rookie mistake, but changing the row parameter when creating a GridLayout for a JPanel in my JFrame, seems to be causing another JPanel to vanish altogether:
Here's the stripped down version of the code:
In the GridBug constructor I set up my layout and put a sub class of JPanel in BorderLayout.CENTER. This does other stuff in my original code, but here just draws a box to show it's being displayed.
Somehow the state of the bottom panel which is added to BorderLayout.PAGE_END causes the center panel to vanish
In particular, changing the GridLayout row parameters to a higher value causes the center panel to vanish, lower values work fine
The code as it is now, does not work on my computer, if I uncomment some of the code to reduce row parameters, or if I don't add the JLabel or subPanels then it works...
I have no idea what I'm doing wrong:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GridBug extends JFrame{
static class ImagePanel extends JPanel{
#Override
public Dimension getPreferredSize(){
return new Dimension(200,200);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
System.out.println("Painting image panel...");
g.setColor(Color.CYAN);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public GridBug() {
setLayout(new BorderLayout());
/*PROBLEM CODE HERE*/
//add center image panel - does not appear depending on GridLayout settings in other panels
ImagePanel centerPanel = new ImagePanel();
add(centerPanel , BorderLayout.CENTER);
//add bottom panel
JPanel bottomPanel = new JPanel();
add(bottomPanel, BorderLayout.PAGE_END);
bottomPanel.setLayout(new GridLayout(6,0)); //doesn't work
// bottomPanel.setLayout(new GridLayout(5,0)); //works
JPanel subPanel = new JPanel();
//if I pass more than 4 or so rows as param to gridlayout,
//then imagePanel is not displayed
subPanel.setLayout(new GridLayout(4,0)); //doesn't work
// subPanel.setLayout(new GridLayout(3, 0)); //works
//if I don't add this label - works
JLabel label = new JLabel("A Label:");
subPanel.add(label);
bottomPanel.add(subPanel); //if I don't add the subPanel it works fine
/*END OF PROBLEM CODE?*/
//set window params
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,400);
setLocationRelativeTo(null);
setVisible(true);
}
public static final void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GridBug();
}
});
}
}
Not sure the exact result you want, so I didn't even try. But the problem you're facing, is one of the reasons, you want to pack() your frame, and not setSize(). You're constricting the preferred sizes of the component. pack() respects the preferred size of all your components, and should be used, rather than setSize()
bottomPanel.setLayout(new GridLayout(6,0)); //doesn't work..
// with pack(), now it does.
pack();
//setSize(400,400); // if you increase the size it'll work also, but just pack()
You just need to work on the laying out of your components now to get your desired look :)
A more detailed explanation of your problem.
This is how you code currently looks when I set the background. Note: you can already see the setSize() is taking a toll on your top panel's preferred size (200, 200).
The top CYAN is your image panel.
The BLUE is the subPanel with 4 row. With GridLayout, all the rows will be at least the size of it largest component. In this case it's the label. You can see the blue area is 4 times the height of the label (as it should be)
Not the RED, which is the bottomPanel. This has 5 rows. The largest component is the subPanel, so the total size of the bottomPanel is the size of the subPanel x 5, as you can also see. Once you add another row, the top panel gets pushed out.
I'm currently trying to fill a JPanel (using GridLayout) with Buttons. These Buttons should be squares having a set width.
The programm should be able to resize the playing field (n*m buttons). Problem is, the buttons are automatically stretched to completely fill the JScrollpane, completely ignoring the set height and width. Thus making the scrollbars unnecessary.
Here is my code:
Creating the panels:
panel_game = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane(panel_game);
Trying to resize the JPanel: (where x and y are the number of buttons and zoomlvl the size)
panel_game.setLayout(new java.awt.GridLayout(x, y));
panel_game.setBounds(panel_game.getX()+5,panel_game.getY()+5,x*zoomlvl-5,y*zoomlvl);
panel_game.setPreferredSize(new Dimension(x*zoomlvl,y*zoomlvl));
And adding the buttons: (f is my playfield, a 2D-Array)(buttons is a Arraylist, containing my buttons)
for(int i=0; i<f.getSize()[0]*f.getSize()[1];i++){
buttons.add(new JButton());
buttons.get(i).setSize(zoomlvl, zoomlvl);
buttons.get(i).setPreferredSize(new Dimension(zoomlvl,zoomlvl));
panel_game.add(buttons.get(i));
}
I have no clue how I can tell Java to stop resizing my buttons etc. automatically.
Help would be appreciated :)
GridLayout is built to fill the container that uses it with components. If the container holding the buttons is constrained in size, then the buttons will stretch or fill to fill that container as closely as possible. A solution may be to nest layout managers so that this does not occur, but I can't give more specific advice without more code, particularly a minimal example program. Images might help too.
If you want to prevent the "button grid panel" from stretching to fill the whole viewport area of the ScrollPane, you could place this grid panel into another panel (with FlowLayout).
In general, you should either
not set the preferred size of the panel_game OR
not set the preferred size of the buttons
because
when you set the preferred size of the buttons, then the preferred size of the panel will be computed from the preferred sizes of the buttons
when you set the preferred size of the panel, then the size of the buttons will be determined by the size of the panel, respectively
Maybe this is what you want to achieve:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class ScrollButtonGrid
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int x = 5;
int y = 5;
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(x, y));
for(int i=0; i<x*y;i++){
JButton button = new JButton(String.valueOf(i));
button.setPreferredSize(new Dimension(100,100));
panel.add(button);
}
JPanel container = new JPanel(new FlowLayout(FlowLayout.CENTER, 0,0));
container.add(panel);
JScrollPane scrollPane = new JScrollPane(container);
f.getContentPane().add(scrollPane);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}