I am just learning Swing. I am trying my best to create a menu for a nutritional value calculator. I don't understand why the setVisibleRowCount() method does not work. I set the value to 1, but the rows are still visible. I would love a good explanation on the problem.
package inFine;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main {
public static void main(String[] args) {
JFrame frame=new JFrame("Calculator Valori nutritive");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500,500);
frame.setLocation(500,100);
frame.setLayout(new BorderLayout());
String []MicDejun= {"Cereale","Ou fiert","Ou prajit","Omleta","Salata rosii","Salata cu bacon ","Ovaz","Sandwitch"};
String []Pranz= {"Spanac","Cartofi prajiti","Linte","Piure","Orez Simplu", "Orez Legume","Brocoli","Piept de pui "
,"Macrou","Somon","Dorada","Ceafa de porc"};
String []Cina= {"Lasagna","Paste","Pizza","Fasole carnati","Encilada","Tigaie picanta","Tigaie tiganeasca","Tocanita"};
String []Snack= {"Chips Lays","Chips Lidl","Chips Carefur","Ciocolata","Corn","Inghetata","Placinta"};
JPanel P_Centru,P_Nord = new JPanel(),P_South=new JPanel();
JPanel P_MicDejun,P_Pranz,P_Cina,P_Snack;
JLabel T_MicDejun=new JLabel("Mic Dejun: ");
JLabel T_Pranz=new JLabel("Pranz: ");
JLabel T_Cina=new JLabel("Cina: ");
JLabel T_Snack=new JLabel("Snack: ");
JList <String>L_MicDejun=new JList<>(MicDejun);
L_MicDejun.setVisibleRowCount(1);
JList <String>L_Pranz=new JList<>(Pranz);
L_Pranz.setVisibleRowCount(1);
JList <String>L_Cina=new JList<>(Cina);
L_Cina.setVisibleRowCount(1);
JList <String>L_Snacks=new JList<>(Snack);
L_Snacks.setVisibleRowCount(1);
JScrollPane scr1=new JScrollPane(L_MicDejun);
JScrollPane scr2=new JScrollPane(L_Pranz);
JScrollPane scr3=new JScrollPane(L_Cina);
JScrollPane scr4=new JScrollPane(L_Snacks);
P_MicDejun=new JPanel();
set(T_MicDejun);
P_MicDejun.add(T_MicDejun);
P_MicDejun.add(L_MicDejun);
P_MicDejun.add(scr1);
P_Pranz=new JPanel();
set(T_Pranz);
P_Pranz.add(T_Pranz);
P_Pranz.add(L_Pranz);
P_Pranz.add(scr2);
P_Cina=new JPanel();
set(T_Cina);
P_Cina.add(T_Cina);
P_Cina.add(L_Cina);
P_Cina.add(scr3);
P_Snack=new JPanel();
set(T_Snack);
P_Snack.add(T_Snack);
P_Snack.add(L_Snacks);
P_Snack.add(scr4);
P_Centru=new JPanel();
P_Centru.setLayout(new GridLayout(4,1));
P_Centru.add(P_MicDejun);
P_Centru.add(P_Pranz);
P_Centru.add(P_Cina);
P_Centru.add(P_Snack);
frame.add(BorderLayout.NORTH,P_Nord);
frame.add(BorderLayout.CENTER,P_Centru);
frame.add(BorderLayout.SOUTH,P_South);
}
public static void set (JLabel a)
{
a.setFont(new java.awt.Font("Arial",Font.PLAIN,12));
a.setForeground(Color.black);
}
}
The fundamental problem is that a component can only appear in one container. The tables are added to the scroll panes in their constructor. They do not need to be separately added to .. anything else. Here is the immediate effect of doing that.
Note: Adding a call to frame.pack(); after everything else in the constructor would make the components in the GUI appear more reliably. There are other problems with the code as well, but the important things are the basics covered above.
Related
I know this question has been asked a lot and I have done my research but still can not find anything. Below is proof of this before anyone gets upset:
I found this link:
https://coderanch.com/t/563764/java/Blank-Frame-Panel
and this:
Adding panels to frame, but not showing when app is run
and this:
Why shouldn't I call setVisible(true) before adding components?
and this:
JPanel not showing in JFrame?
But the first question says use repaint which I tried with no fix and the second and third to last questions talk about putting setVisible after components added which I have.
The last one talks about making the users JPanelArt a extension (done so) of JPanel instead of JFrame and not to make a frame in a frame constructor (also have not done)
When ever I run this I just get a blank frame, as if the panel was never added in.
I apologise if I have missed something in those links. Anyway below is my classes:
GUI.java (extends JFrame)
package javaapplication2;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GUI extends JFrame{
public GUI(String name) {
super(name);
getContentPane().setLayout(null);
JPanel myPanel1 = new GUIPanel();
myPanel1.setLocation(20, 20);
getContentPane().add(myPanel1);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setResizable(true);
}
public static void main(String[] args) {
JFrame frame = new GUI("Game");
frame.setVisible(true);
}
}
GUIPanel.java (extends JPanel)
package javaapplication2;
import java.awt.*;
import javax.swing.*;
public class GUIPanel extends JPanel {
JButton start;
JButton inspect1;
JButton inspect2;
JButton inspect3;
JButton suspect;
public GUIPanel() {
setLayout(new BorderLayout());
start = new JButton("Start Game");
inspect1 = new JButton("Inspect 1");
inspect2 = new JButton("Inspect 2");
inspect3 = new JButton("Inspect 3");
suspect = new JButton("Choose Suspect");
add(start, BorderLayout.WEST);
add(inspect1, BorderLayout.WEST);
add(inspect2, BorderLayout.WEST);
add(inspect3, BorderLayout.WEST);
add(suspect, BorderLayout.WEST);
}
}
I know it is very simple, but that is because I am following a tutorial from my lecturer to get the hang of things as I previously used a GUI builder which someone in this community pointed out to me is not good to start with (very correct!)
The issue lies in your GUI class when you call getContentPane().setLayout(null). Because of this method call, your JFrame is not displaying anything. If you remove it, your elements should show up.
I also noticed that you were setting each JButton to have a constraint of BorderLayout.WEST. This will most likely put your JButtons on top of each other and render only one of them.
I'm writing a Java GUI application, and is something like this:
JPanel main = new JPanel(new GridLayout(1, 1));
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
main.add(buttonPanel)
I want to add a button to the grid, but i want it centered on the grid panel.
Adding the button to another JPanel allows me to center it to the Grid.
Is there any shorter way to do this?
For example:
JPanel main = new JPanel(new GridLayout(1, 1));
JPanel buttonPanel = JPanel();
main.add(new JPanel().add(button));
This is not working for me.
Thanks :)
I agree with the other commenters that reducing the number of lines of code probably isn't as neccessary as you think it is: Generally speaking, your goal should be to reduce code complexity, not code length, and efforts to minimize length often lead to code that is more complex/hard to understand rather than less.
That said, applying basic OO principles can enable you to shorten your code while maintaining (if not increasing) its clarity:
class CenteredContentPanel extends JPanel {
CenteredContentPanel(JComponent addTo){
this.setLayout(new GridLayout(1,1));
JPanel parentPanel = new JPanel();
parentPanel.add(addTo);
this.add(parentPanel);
}
}
Now, you can add as many of these as you please to a parent container with a single line of code:
JPanel main = new JPanel();
main.add(new CenteredContentPanel(button));
//repeat above line to add as many "centered" components as you need to
(code is untested, as I don't have access to an IDE at the moment, but you get the gist...)
You need to add main to the frame:
add(main.add(new JPanel().add(button)));
This works fine for me:
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MyFrameClass extends JFrame
{
public MyFrameClass(){
JPanel main = new JPanel(new GridLayout(1, 1));
JButton button = new JButton();
add(main.add(new JPanel().add(button)));
setSize(800,600);
setVisible(true);
}
public static void main (String [] args)
{
new MyFrameClass();
}
}
I'm trying to align a JLabel to the right in a JPanel. I'm adding a JTabbedPane, a JPanel which contains my JLabel and JTextArea to a main JPanel.
I have searched SO and tried some methods like setAlignmentX, setHorizontalAlignment(SwingConstants.LEFT) and nested containers to no avail.
Here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class LabelProblem
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Label Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel Main = new JPanel();
Main.setLayout(new BoxLayout(Main, BoxLayout.Y_AXIS));
JPanel ComponentPanel = new JPanel();
JLabel label = new JLabel("Sample Text");
label.setHorizontalAlignment(SwingConstants.LEFT);
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
label.setAlignmentX(Component.RIGHT_ALIGNMENT);
ComponentPanel.add(label);
JTabbedPane Tab = new JTabbedPane();
Tab.add("Document 1", new JPanel());
Main.add(Tab);
Main.add(ComponentPanel);
JTextArea Area = new JTextArea(10,10);
JScrollPane Scroll = new JScrollPane(Area);
frame.add(Main);
frame.add(Scroll, BorderLayout.SOUTH);
frame.setSize(450,450);
frame.setVisible(true);
}
}
How can I align my JLabel to the right?
Thanks!
So, the place of that label is determined by the layout of ComponentPanel. Since you didn't specify any layout it is using the default FlowLayout with a CENTER alignment. Assuming that you are ok with a FlowLayout it is a mere question of setting the alignment of the LEFT since this is possible with this layout.
Here's the code with the fix, however I suspect that as you put more elements to the ComponentPanel you will want to use another layout since FlowLayout is more adequate for menus and the like and not for displaying the main content.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
class LabelProblem
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
initGUI();
}
});
}
public static void initGUI()
{
JFrame frame = new JFrame("Label Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
JPanel componentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel label = new JLabel("Sample Text");
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
componentPanel.add(label);
JTabbedPane Tab = new JTabbedPane();
Tab.add("Document 1", new JPanel());
main.add(Tab);
main.add(componentPanel);
JTextArea area = new JTextArea(10, 10);
JScrollPane scroll = new JScrollPane(area);
frame.add(main);
frame.add(scroll, BorderLayout.SOUTH);
frame.setSize(450, 450);
frame.setVisible(true);
}
}
Result:
Note: I also changed the variable names to follow the java style convention: variable names should start with lower case to differenciate them from clases names, starting in upper case.
One simple approach is to set the label's horizontalAlignment to JLabel.RIGHT in the constructor.
import java.awt.*;
import javax.swing.*;
class LabelProblem {
public static void main(String[] args) {
JFrame frame = new JFrame("Label Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1));
JTabbedPane tab = new JTabbedPane();
tab.add("Document 1", new JPanel());
frame.add(tab);
JLabel label = new JLabel("Sample Text", JLabel.RIGHT);
frame.add(label);
JTextArea area = new JTextArea(10, 10);
JScrollPane scroll = new JScrollPane(area);
frame.add(scroll);
frame.pack();
frame.setSize(450, 450);
frame.setVisible(true);
}
}
I think it may be a matter of you not actually setting layouts where you imagine you're setting layouts.
You have a JPanel with a vertically oriented BoxLayout (Main) enclosing another JPanel with default layout (ComponentPanel), finally enclosing your label. The reason why your label can't be pushed to the right is because is already is pushed to the right within it's enclosing container. If you set a colored border around ComponentPanel, you'll see what I mean -- it only occupies the same amount of space as the JLabel, giving the JLabel nowhere to move.
You need to set a layout and constraints for your intermediate ComponentPanel, allowing it to horizontally fill its parent container so that the label has someplace to go.
You haven't really specified how your layout is supposed to look, but if you change the layout on Main to X_AXIS, your label will pop over to the left (as will its parent container). Without knowing what you're really trying to do, I can't say much more.
I would however, suggest you throw your BoxLayout away entirely and look into using GridBagLayout, which gives you a high level control over your UI. GridBagLayout isn't the most concise construct, but that's the price of control.
I am trying to put a text area onto a dialog box using Java Swing. I have a problem of setting the size of this JTextArea. The width of the text area is always equal to the whole width of the window and stretches with the window if I resize it.
private void arrangeComponents() {
JTextArea textArea = new JTextArea();
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(textArea);
outerPanel.add(scrollPane, BorderLayout.CENTER);
Container contentPane = getContentPane();
contentPane.add(outerPanel, BorderLayout.CENTER);
}
I want the JTextArea to be horizontally aligned to the centre of the window and does not change its size.
What did I do wrong?
Use the JTextArea(int rows, int columns) constructor that specifies rows and columns, as shown here, and don't neglect to pack() the enclosing Window.
outerPanel.add(scrollPane, BorderLayout.CENTER);
A BoxLayout doesn't take constraints, so the BorderLayout.CENTER is unnecessary.
The problem is that a BoxLayout respects the maximum size of the component which for a scrollpane is set very large.
Instead of using a BoxLayout, just use a panel with a FlowLayout.
Run the example below to see what you are currently doing. Then comment out the setLayout(...) statement and run again. By default the panel uses a FlowLayout so you will get what you want.
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
setLayout( new BoxLayout(this, BoxLayout.PAGE_AXIS));
JTextArea textArea = new JTextArea(5, 30);
JScrollPane scrollPane = new JScrollPane(textArea);
//scrollPane.setMaximumSize( scrollPane.getPreferredSize() );
add(scrollPane);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SSCCE() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Or if you really want to keep the BoxLayout then leave keep the setLayout(...) statement and then set the maximum size equal to the preffered size. Many people will say you should never invoke a "setXXX()" method directly and instead you should override the setMaximumSize() method of the scrollpane to just return the preferred size.
Note, when testing these two solutions make sure you make the window smaller than the scrollpane to see how each layout works differently.
i found this from a simple coding site. This code sample may be useful for you.
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class JTextAreaTest {
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("JTextArea Test");
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String text = "A JTextArea object represents a multiline area for displaying text. "
+ "You can change the number of lines that can be displayed at a time, "
+ "as well as the number of columns. You can wrap lines and words too. "
+ "You can also put your JTextArea in a JScrollPane to make it scrollable.";
JTextArea textAreal = new JTextArea(text, 5, 10);
textAreal.setPreferredSize(new Dimension(100, 100));
JTextArea textArea2 = new JTextArea(text, 5, 10);
textArea2.setPreferredSize(new Dimension(100, 100));
JScrollPane scrollPane = new JScrollPane(textArea2,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
textAreal.setLineWrap(true);
textArea2.setLineWrap(true);
frame.add(textAreal);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
}
Just call that method for ur text area: setLineWrap(true);
If JTextArea is initializated
JTextArea text = new JTextArea(int rows, int columns)
you just call the method text.setLineWrap(true)
then text'size is fixed.
So I have a slight issue with adding two JPanels to a main main panel. I've put it as a quick example of what I want to do since you don't want to be looking through loads of lines of unnecessary code :). I want panel one to be added first (north) and then panel two (south). I've tried using Border layout and positioning them invoking north and south on BorderLayout when adding the panels but still no luck.
Thanks in advance.
private JPanel one,two;
public Example(){
one = new JPanel();
one.setSize(new Dimension(400,400));
two = new JPanel(new GridLayout(7,8));
two.setSize(new Dimension(400,400));
one.setBackground(Color.BLACK);
two.setBackground(Color.BLUE);
JPanel mainpanel = new JPanel();
mainpanel.setBackground(Color.orange);
mainpanel.add(one);
mainpanel.add(two);
add(mainpanel);
setSize(500,500);
setVisible(true);
}
If you want to use BorderLayout, then BorderLayout.CENTER takes up as much space as it can, and the other directions take only what they need. If you add extra stuff to the JPanels, they will get bigger, based on the needs of the objects they contain.
If you want to just divide the space evenly within the main JPanel, try this:
JPanel mainpanel = new JPanel(new GridLayout(2, 1));
That creates a GridLayout with 2 rows and 1 column...
Try this code. There was issue that apparently if you install grid layout on a panel and you add no components it will not take space.
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame
{
private JPanel one, two;
public Example()
{
one = new JPanel();
two = new JPanel();///new GridLayout(7, 8));
one.setBackground(Color.BLACK);
two.setBackground(Color.BLUE);
JPanel mainpanel = new JPanel(new BorderLayout());
mainpanel.setBackground(Color.orange);
mainpanel.add(one, BorderLayout.NORTH);
mainpanel.add(two, BorderLayout.SOUTH);
setContentPane(mainpanel);
setSize(500, 500);
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
Example f = new Example();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}
GridLayout ignores the values set in setSize method of contained components. If you want to control the size of each component, consider using GridBagLayout.