I anted to add a JPanel to my already existing JPanel so I could have a small window with a JTextField on top with a name and a scrollable JTextArea below it with some description. I made a class that extends JPanel with the following constructor:
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
public class LocationWindow extends JPanel {
public JTextField name;
public JTextArea desc;
public JScrollPane scroll;
public LocationWindow(){
super();
setBorder (new TitledBorder(new EtchedBorder(), "Display Area"));
setLayout(new BorderLayout());
setVisible(true);
setBounds(30, 40, 700, 290);
name = new JTextField(10);
name.setText("name");
desc = new JTextArea(5,10);
scroll = new JScrollPane(desc);
scroll.setVerticalScrollBarPolicy ( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );
desc.setEditable (true);
desc.setLineWrap(true);
desc.setText("random text");
add(name);
add(desc);
add(scroll);
validate();
}
}
It almost works, as it gives me the window with the borders and a scroll, but both the JTextField and JTextArea are missing.
As you are using BorderLayout for the JPanel,
setLayout(new BorderLayout());
the components will always be added to the center if you dont specify the position. add(scroll); is same as add(scroll,BorderLayout.CENTER); as you're adding all via add the last added component only be visible.Refer this as well
The next is you are adding JTextArea seperately so it will be removed from ScrollPane.Just add scrollpane to Panel no need to add all components.[Add the parent component alone]
add(name,BorderLayout.NORTH);
//add(desc);Noo need to add desc as it is already added in JScrollPane
add(scroll,BorderLayout.CENTER);
There is no need for setVisible for JPanel.JPanel needs to be embedded in Container like JFrame to be visible
//setVisible(true);Wont do anything
So call like this
JFrame frame = new JFrame();
frame.add(new LocationWindow());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
You can use below code to adding panel to panel.
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
LocationWindow loc = new LocationWindow();
frame.add(loc);
frame.setSize(300, 200);
frame.setVisible(true);
}
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 don't understand why the panel.add(txtnum1) and panel.add(button2) doesn't show up when I compile the program. The panel.add(button) works just fine, my compiler doesn't throw any warning or errors, did I miss something?
package gui;
import javax.swing.*;
import java.awt.*;
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(new Dimension(300, 500));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.GRAY);
frame.getContentPane().add(panel);
JButton button = new JButton("Submit");
panel.add(button);
JTextField txtnum1 = new JTextField();
txtnum1.setPreferredSize(new Dimension(30, 50));
panel.add(txtnum1);
JButton button2 = new JButton("Clear");
panel.add(button2);
}
}
When implementing GUI applications with Swing, I like to have this approach in the code that builds the JFrame (we assume a simple GUI that does not have JPanel containers inside JPanel containers and stuff like that):
Create JFrame and initialize it
Create JPanel
Create GUI components for that panel and add them
Add panel to the JFrame (repeat from 2) for every JPanel inside the JFrame)
Make the JFrame visible on the screen
So, your code would look something like this:
package gui;
import javax.swing.*;
import java.awt.*;
public class GUI {
public static void main(String[] args) {
/* step 1 */
JFrame frame = new JFrame();
frame.setSize(new Dimension(300, 500));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* step 2 */
JPanel panel = new JPanel();
panel.setBackground(Color.GRAY);
/* step 3 */
JButton button = new JButton("Submit");
panel.add(button);
JTextField txtnum1 = new JTextField();
txtnum1.setPreferredSize(new Dimension(30, 50));
panel.add(txtnum1);
JButton button2 = new JButton("Clear");
panel.add(button2);
/* step 4 */
frame.getContentPane().add(panel);
/* step 5 */
frame.setVisible(true);
}
}
Tested and it works in Eclipse.
You should call setVisible(true) at the end, after all components have been added.
Put frame.setVisible(true); at the end and it will work as expected.
I want to add an object of type JPanel to a JFrame.
I'm trying this, but the Jpanel is not added.
the idea is: Add to P2 a P5 that has the components defined in class P5.
What could be happening ?, I do not want to create all the JPanel in the class First_view, since the code would be messed up a lot.
CODE:
import javax.swing.*;
import java.awt.*;
public class First_view extends JFrame {
Container Frame;
public First_view() {
super("title");
Frame = this.getContentPane();
Frame.setLayout(new BorderLayout());
Frame.add((new P2()), BorderLayout.WEST);
setSize(900, 500);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
class P2 extends JPanel {
public P2() {
this.setLayout(new BorderLayout());
add((new P5()), BorderLayout.NORTH);
}
}
class P5 extends JPanel {
JScrollPane informacion = new JScrollPane(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JTextArea T1 = new JTextArea();
public P5() {
setLayout(new FlowLayout());
setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 0));
add(setInformacion());
}
private JScrollPane setInformacion() {
T1.append("Information, bla bla bla");
T1.setEditable(false);
T1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
T1.setLineWrap(true);
informacion.add(T1);
informacion.setBorder(BorderFactory.createLineBorder(Color.BLACK));
return informacion;
}
}
PIC:
The component to display in the JScrollPane should not be added, use setViewportView instead.
private JScrollPane setInformacion() {
T1.append("Information, bla bla bla");
...
informacion.setViewportView(T1);
...
informacion.setBorder(BorderFactory.createLineBorder(Color.BLACK));
return informacion;
}
Obs: the arguments passed to the constructor of JScrollPane are in the wrong order, that is, the vertical police comes first:
JScrollPane informacion = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
Edit: as Andrew commented it is not a good idea to extend a class just to use it (JFrame, JPanel). Example, I tried not to change too much of your original flow:
package cfh.test;
import javax.swing.*;
import java.awt.*;
public class FirstView {
private JFrame frame;
private JTextArea informacionText; // not sure if that is needed as field
public FirstView() {
informacionText = new JTextArea();
informacionText.setEditable(false);
informacionText.setBorder(BorderFactory.createLineBorder(Color.BLACK));
informacionText.setLineWrap(true);
informacionText.append("Information, bla bla bla");
JScrollPane scrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
scrollPane.setViewportView(informacionText);
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new FlowLayout());
infoPanel.add(scrollPane);
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BorderLayout());
leftPanel.add(infoPanel, BorderLayout.NORTH);
// TODO consider moving above code to an own method returning the left panel
frame = new JFrame("title");
frame.setLayout(new BorderLayout());
frame.add(leftPanel, BorderLayout.WEST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(900,500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I am trying to resize the JPanels but there is a space under it . Here is a link to show :
And this is the code :
import java.awt.*;
import javax.swing.*;
public class Ex1 extends JFrame{
private JTextArea textarea = new JTextArea ();
private JTextField field = new JTextField ();``
private JButton buton = new JButton ("Trimite");
public Ex1(){
JPanel panel = new JPanel (new BorderLayout(2,2));
JPanel panel1 = new JPanel (new BorderLayout(2,2));
JPanel panel2 = new JPanel (new BorderLayout(2,2));
JLabel label1 = new JLabel ("Mesaje");
JLabel label2 = new JLabel ("Scrieti un mesaj");
panel1.setPreferredSize(new Dimension(350,100));
panel2.setPreferredSize(new Dimension(350,25));
panel1.add(label1, BorderLayout.NORTH);
panel1.add(textarea, BorderLayout.CENTER);
panel2.add(label2, BorderLayout.WEST);
panel2.add(field, BorderLayout.CENTER);
panel2.add(buton, BorderLayout.EAST);
setLayout(new GridLayout(2,1,1,1));
panel.add(panel1, BorderLayout.NORTH);
panel.add(panel2, BorderLayout.CENTER);
add(panel);
}
public static void main(String[] args) {
JFrame frame = new Ex1();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
You are setting a layout for a frame to GridLayout in which all components are given equal size. You have two rows, add(panel) adds the panel to the first row of the grid. The second row is left empty. See How to Use GridLayout.
Comment out setLayout(new GridLayout(2,1,1,1)); and the extra space should go away. When you comment this line the layout of frame's content pane will be BorderLayout. The default layout of the JFrame is BorderLayout. So add(panel); will add the panel to the center of the frame's content pane. As a result the panel should occupy all the available space.
As a side note, avoid setPreferredSize(), usually it is not necessary, see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing for details.
You can specify the number of rows and columns for a text area and wrap it in the scroll pane, ie:
textArea = new JTextArea(5, 20);
JScrollPane scrollPane = new JScrollPane(textArea);
For more details see How to Use Text Areas
EDIT: example of getPreferredSize()
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
public class Ex1 extends JPanel{
private JTextArea textarea = new JTextArea ();
private JTextField field = new JTextField ();
private JButton buton = new JButton ("Trimite");
public Ex1() {
setLayout(new BorderLayout());
JPanel panel1 = new JPanel (new BorderLayout(2,2));
JPanel panel2 = new JPanel (new BorderLayout(2,2));
JLabel label1 = new JLabel ("Mesaje");
JLabel label2 = new JLabel ("Scrieti un mesaj");
panel1.add(label1, BorderLayout.NORTH);
panel1.add(new JScrollPane(textarea), BorderLayout.CENTER);
panel2.add(label2, BorderLayout.WEST);
panel2.add(field, BorderLayout.CENTER);
panel2.add(buton, BorderLayout.EAST);
add(panel1, BorderLayout.CENTER);
add(panel2, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(350, 300);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
Ex1 panel = new Ex1();
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
}
You need to resize the JFrame not the JPanel. Try:
this.setPreferredSize(new Dimension(350, 25);// in Ex1
Or in your main method:
frame.setPreferredSize(new Dimension(350, 25);
I'm having an issue with my Java program where I can add a JButton to the panel in JFrame, but when I create an JTextArea object, the JButton disappears?
package sandBox;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
JFrame frame = new JFrame("Hello world");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600,500);
frame.setLayout(new BorderLayout());
JButton button2 = new JButton("STOP");
JButton button1 = new JButton("GO");
JTextArea text1 = new JTextArea();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(button1, BorderLayout.SOUTH);
panel.add(button2, BorderLayout.NORTH);
frame.add(panel);
}
}
Remember
BorderLayout will only allow a single component to occupy each of the available positions. Adding another component will cover the previous component
Where possible, always call setVisible after you've created the UI
To actually add all your components, your example doesn't actually add the JTextArea to the container
Someone like...
//...
// frame.setVisible(true);
//...
frame.add(text1);
frame.add(panel, BorderLayout.SOUTH);
frame.setVisible(true);
Might help