JPanel consuming entire JFrame - java

I am creating a Java application which has a login screen. Right now I am designing the login screen. I use a Panel in a JFrame, which is positioned at BorderLayout.CENTER, and then set the layout of the Panel as GridLayout(3,1). Right now my application looks like this:
I want to design my JFrame like this:
Here the grey portion is the JFrame and the red portion is the Panel which has the login screen, TextField's and Button's. I don't want the TextField and Button's on the entire screen.
This is what I did right now
public class MailClient {
JFrame loginScreen;
JTextField emailid;
JPasswordField password;
JButton login;
Dimension loginScreenSize;
JPanel entireLogin;
BorderLayout mainLayout;
public static void main (String args[])
{
MailClient obj = new MailClient();
obj.build();
}
public void build()
{
mainLayout = new BorderLayout(40, 40);
loginScreenSize = new Dimension(300,300);
loginScreen = new JFrame("MailClient");
loginScreen.setSize(loginScreenSize);
loginScreen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
loginScreen.setResizable(false);
loginScreen.setLocationRelativeTo(null);
loginScreen.setLayout(mainLayout);
entireLogin = new JPanel();
entireLogin.setLayout(new GridLayout(3,1));
emailid = new JTextField();
password = new JPasswordField();
login = new JButton("LOGIN");
entireLogin.add(emailid);
entireLogin.add(password);
entireLogin.add(login);
loginScreen.add(entireLogin, BorderLayout.CENTER);
loginScreen.setVisible(true);
}
}

Add an empty border of the thickness you find appropriate around the centered JPanel if you want it to have a border to the edge (if it resizes, for example).
myPanel.setBorder(new EmptyBorder(int, int, int, int))
Set the maximum size for the centered JPanel if you want to prevent it from being made larger by the BorderLayout CENTER normal workings.
myPanel.setMaximumSize(new Dimension(x, y))

Related

Java Swing JTabbedPane layout

I am new to Swing and cannot find a page that helps me understand JTabbedPane. I cannot find a way to control the layout of components of the tabbed panels. I can layout each of my panels correctly as separate GUIs but not in a tabbed pane like I need to do. I would like to use the BorderLayout not FlowLayout.
Also, you can see I'm trying to use colors to keep track of my panels and their components. I cannot set the background of the JTabbedPane. It is still the default grey. Can someone tell me why this is?
Thank you for any advice you can give.
What I have so far appears to follow a 'flow layout' despite any changes I've tried
(Methods have been removed or nearly removed to keep code shorter)
public class GUIFrame extends JFrame {
public GUIFrame(String title) {
JFrame frame = new JFrame(title);
Container c = frame.getContentPane();
buildGUI(c);
setFrameAttributes(frame);
}
private void buildGUI(Container c) {
c.setLayout(new BorderLayout());
c.setBackground(Color.BLACK);
JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
tabs.setBackground(Color.YELLOW);
c.add("Center", tabs);
tabs.addTab("Specialty", new SpecialtyPanel());
tabs.addTab("Treatment", new TreatmentPanel());
tabs.addTab("Doctor", new DoctorPanel());
tabs.addTab("Patient", new PatientPanel());
}
private void setFrameAttributes(JFrame f) {
f.setSize(500, 500);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
MedicalSystemIO test = new MedicalSystemIO();
new GUIFrame("Tabbed Title");
}
public class SpecialtyPanel extends JPanel implements ActionListener {
JTextField jteInput = null;
DefaultListModel<String> model = new DefaultListModel<String>();
JList<String> list = new JList(model);
JScrollPane pane = new JScrollPane(list);
public SpecialtyPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.black));
buildGUI(panel);
}
private void buildGUI(JPanel panel) {
JPanel jpaInput = createInputPanel();
JPanel jpaProcess = createProcessPanel();
JPanel jpaOutput = createOutputPanel();
//panel.setLayout(new BorderLayout());
add("North", jpaInput);
add("Center", jpaProcess);
add("South", jpaOutput);
}
private JPanel createInputPanel() {
JPanel jpaInput = new JPanel();
jpaInput.setBackground(Color.RED);
return jpaInput;
}
private JPanel createProcessPanel() {
JPanel jpaProcess = new JPanel();
jpaProcess.setBackground(Color.BLUE);
return jpaProcess;
}
private JPanel createOutputPanel() {
JPanel jpaOutput = new JPanel();
jpaOutput.add(pane);
return jpaOutput;
}
The SpecialtyPanel is shown that way (flow layout) as you are putting the components on it in the wrong way:
No need for passing a new panel into the buildGUI method as you want to put them directly on the SpecialtyPanel which already is a JPanel,
you commented out the setting of the BorderLayout and
you used the wrong notation of passing the layout constraints in the add methods.
Your constructor and build method should look like this:
public SpecialtyPanel() {
buildGUI();
}
private void buildGUI() {
setBorder(BorderFactory.createLineBorder(Color.black));
JPanel jpaInput = createInputPanel();
JPanel jpaProcess = createProcessPanel();
JPanel jpaOutput = createOutputPanel();
setLayout(new BorderLayout());
add(jpaInput, BorderLayout.NORTH);
add(jpaProcess, BorderLayout.CENTER);
add(jpaOutput, BorderLayout.SOUTH);
}
To have the panel another color than gray you have to color the component that is put on the tabbed pane as it covers the whole space. Add the desired color to the buildGUI method, e.g.:
private void buildGUI(JPanel panel) {
// ...
setBackground(Color.YELLOW);
}
As a JPanel is opaque by default (that means not transparent), you need to set panels on top (except those which you colored explicitly) to be transparent. In case of SpecialtyPanel:
private JPanel createOutputPanel() {
JPanel jpaOutput = new JPanel();
jpaOutput.add(pane);
jpaOutput.setOpaque(false); // panel transparent
return jpaOutput;
}

JPanel won't display components when layout is null

I'm trying to create a GUI, and I want to place elements in certain places. I made the layout of my panel null, so I could do this. However, Nothing will appear when the panel is null. Here's the code:
public class OverView extends JFrame {
//height and width of screen
Toolkit tk = Toolkit.getDefaultToolkit();
int x = ((int) tk.getScreenSize().getWidth());//length of screen
int y = ((int) tk.getScreenSize().getHeight());//height
//components
private JLabel title;
private JLabel description;
private JPanel panel;
private ArrayList<JButton> farms;
//farm variables
public ArrayList<Farm> owned;
public OverView(ArrayList<Farm> owned) {
super("The Lolipop Farm - Overview");
setSize(700, 700);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
//initialize variables
this.owned = owned;
panel = new JPanel();
panel.setLayout(null);
title = new JLabel("<html>Your Farms - The Lolipop Farm"
+ "<br> <font size=1000> <i> An Eph Production </i> </font></html>");
//set background color, color, and font of JComponents
title.setFont(new Font("serif", Font.BOLD, 25));
title.setBackground(Color.GRAY);
title.setOpaque(true);
//set size and location of the components
title.setSize(350, 120);
title.setLocation(x / 2, 600);
//add to panel
panel.add(title);
//add panel to the screen
add(panel);
}
}
Why isn't the panel showing anything when the layout's null?
As Overview is a Frame, I think you must call the method
setVisible(true);
according to https://docs.oracle.com/javase/tutorial/uiswing/layout/using.html in order to make it visible .
Now, if that doesn't work, I wonder if you have created an instance of the Overview class somewhere else in your code, or in the Main method. If you haven't, then there is no object that can show the panel inside of your class so your program won't show anything.
Your problem is with the code
setLayout(null);
This will set the layout of the JFrame to null since you are extending (inheriting it). You must have a layout for a JFrame although you can do without layout for JPanel. Just remove that line and it will be fine.
EDIT:
And of course you need to call setVisible(true) like the other guy said.

How to remove the padding between in the JPanel still using a flow layout?

Here's the portion of my java application GUI that I have a question about.
What this GUI consists is a blue JPanel(container) with default FlowLayout as LayoutManager that contains a Box which contains two JPanels(to remove the horizontal spacing or i could have used setHgaps to zero for that matter instead of a Box) that each contains a JLabel.
Here's my code for creating that part of the GUI.
private void setupSouth() {
final JPanel southPanel = new JPanel();
southPanel.setBackground(Color.BLUE);
final JPanel innerPanel1 = new JPanel();
innerPanel1.setBackground(Color.ORANGE);
innerPanel1.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
innerPanel1.add(new JLabel("Good"));
final JPanel innerPanel2 = new JPanel();
innerPanel2.setBackground(Color.RED);
innerPanel2.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
innerPanel2.add(new JLabel("Luck!"));
final Box southBox = new Box(BoxLayout.LINE_AXIS);
southBox.add(innerPanel1);
southBox.add(innerPanel2);
myFrame.add(southPanel, BorderLayout.SOUTH);
}
My question is how would i get rid the vertical padding between the outer JPanel(the blue one) and the Box?
I know this is padding because i read on Difference between margin and padding? that "padding = space around (inside) the element from text to border."
This wouldn't work because this has to due with gaps(space) between components.- How to remove JPanel padding in MigLayout?
I tried this but it didn't work either. JPanel Padding in Java
You can just set the gaps in the FlowLayout, i.e.
FlowLayout layout = (FlowLayout)southPanel.getLayout();
layout.setVgap(0);
The default FlowLayout has a 5-unit horizontal and vertical gap. Horizontal doesn't matter in this case as the BorderLayout is stretching the panel horizontally.
Or simple initialize the panel with a new FlowLayout. It'll be the same result.
new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
Edit:
"I tried that, didn't work.."
Works for me...
Setting the gap ↑ Not setting the gap ↑
import java.awt.*;
import javax.swing.*;
public class Test {
public void init() {
final JPanel southPanel = new JPanel();
FlowLayout layout = (FlowLayout)southPanel.getLayout();
layout.setVgap(0);
southPanel.setBackground(Color.BLUE);
final JPanel innerPanel1 = new JPanel();
innerPanel1.setBackground(Color.ORANGE);
innerPanel1.add(new JLabel("Good"));
final JPanel innerPanel2 = new JPanel();
innerPanel2.setBackground(Color.RED);
innerPanel2.add(new JLabel("Luck!"));
final Box southBox = new Box(BoxLayout.LINE_AXIS);
southBox.add(innerPanel1);
southBox.add(innerPanel2);
southPanel.add(southBox); // <=== You're also missing this
JFrame myFrame = new JFrame();
JPanel center = new JPanel();
center.setBackground(Color.yellow);
myFrame.add(center);
myFrame.add(southPanel, BorderLayout.SOUTH);
myFrame.setSize(150, 100);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setLocationByPlatform(true);
myFrame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Test().init();
}
});
}
}
Note: Always post a runnable example (as I have done) for better help. You say it doesn't work, but it always works for me, so how would we know what you're doing wrong without some code that will run and demonstrate the problem?

How do I resize JScrollPane after resizing a JTextArea

My JFrame Consists of three main parts a banner at top scrollpane containing a JTextArea center and a JTextField at the bottom. When I re-size the frame I adjust the columns and rows in my JTextArea. When making the frame larger the JTextArea expands visually but removes the scroll-bar. Then if I make the frame smaller the JTextArea stays the same size. This Is where I attempt to re-size my JTextArea.
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
Why would the ScrollPane not re adjust to the change in size of the TextField.
The Rest of the code is below in case it is needed.
public class window extends JFrame
{
private static JFrame frame = new JFrame("Lillian");
private static JButton inputButton = new JButton("Send");
private static JTextField editTextArea = new JTextField(46);
private static JTextArea uneditTextArea = new JTextArea(26,50);
private static JPanel logoPanel = new JPanel();//Input text window
private static JPanel itextPanel = new JPanel();//Input text window
private static JPanel submitPanel = new JPanel();//Submit Button
private static JPanel bottom = new JPanel();//will contain scrollpane
private static JPanel middle = new JPanel();//willcontain itextpanel & submitbutton
private static JPanel otextPanel = new JPanel();//Text Output
public static void runWindow()
{
ImageIcon logo = new ImageIcon("Lillian_resize.png");//banner
ImageIcon icon = new ImageIcon("Lillian_icon.png");//application icon
frame.setIconImage(icon.getImage());
frame.setSize(660,640);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
logoPanel.setSize(10,10);
JLabel logoLabel = new JLabel(logo);
final JScrollPane scrollPane = new JScrollPane(otextPanel);//adds text to panel will scrollbar
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);//scrollbar only apears when more text than screen
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);//scrollbar never apears
scrollPane.setBorder(BorderFactory.createEmptyBorder());
logoPanel.add(logoLabel);
submitPanel.add(inputButton);
itextPanel.add(editTextArea);
otextPanel.add(uneditTextArea);
frame.getContentPane().add(logoPanel,"North");
frame.getContentPane().add(middle);
frame.getContentPane().add(bottom,"South");
middle.add(scrollPane,"North");//adds panels to outer panel
bottom.add(itextPanel, "West");
bottom.add(submitPanel, "East");
uneditTextArea.setLineWrap(true);
uneditTextArea.setWrapStyleWord(true);
uneditTextArea.setEditable(false);
uneditTextArea.setCaretPosition(uneditTextArea.getDocument().getLength());
frame.revalidate();//refreshes screen
//---------------wait for action------------
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
}
}
There should be no need to use a ComponentListener to resize components. That is the job of the layout managers that you use to dynamically resize the components.
You should not be adding the text area to a JPanel first. Instead when using text areas you would generally add the text area directly to the viewport of a JScrollPane by using code like:
JScrollPane scrollPane = new JScrollPane( textArea );
Then you add the scrollpane to the frame with code like:
frame.add(scrollPane, BorderLayout.CENTER);
As you have noticed you should also NOT use hardcoded literals like "Center". Instead use the variables provided by the layout manager. Since you are using a BorderLayout, use the variables defined in the BorderLayout class.
Also, you should NOT be using static variable to create your GUI. I suggest you read the section from the Swing tutorial on Layout Manager. The tutorial will give you more information and the example code will show you how to better structure your program so that you don't need to use static variables.

Changing layout of a JPanel sent to JOptionPane with the pane still running

Trying to change the look of a JOptionPane while its open, depending on which radiobutton the user clicks. What am I doing wrong? It works perfect if I for example add a button and move a JLabel from side to side of the window.
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import static javax.swing.JOptionPane.*;
public class ChangePanel extends JFrame{
private JButton click = new JButton("CLICK ME!");
ChangePanel(){
add(click, BorderLayout.SOUTH);
click.addActionListener(new ButtonListen());
setVisible(true);
setSize(300,100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public class ButtonListen implements ActionListener{
public void actionPerformed(ActionEvent e){
PopUpPanel pop = new PopUpPanel();
showConfirmDialog(ChangePanel.this, pop, "Changeable", OK_CANCEL_OPTION);
}
}
//Send this as Parameter to the ConfirmDialog
public class PopUpPanel extends JPanel implements ActionListener{
JRadioButton jewelry = new JRadioButton("Jewelry");
JRadioButton shares = new JRadioButton("Shares");
JRadioButton machine = new JRadioButton("Machine");
PopUpPanel(){
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
ButtonGroup bg = new ButtonGroup();
JPanel north = new JPanel();
bg.add(jewelry);
jewelry.addActionListener(this);
bg.add(shares);
shares.addActionListener(this);
bg.add(machine);
machine.addActionListener(this);
north.add(jewelry);
north.add(shares);
north.add(machine);
add(north);
}
//Listener for RadioButtons
public void actionPerformed(ActionEvent e){
JTextField info1Txt = new JTextField(12);
JTextField info2Txt = new JTextField(12);
JTextField info3Txt = new JTextField(3);;
JRadioButton b = (JRadioButton)e.getSource();
if(b.getText().equals("Jewelry")){
//Dummy test text
System.out.println("Jewelry");
JPanel info1 = new JPanel();
info1.add(new JLabel("info1:"));
info1.add(info1Txt);
add(info1);
JPanel info2 = new JPanel();
info2.add(new JLabel("info2:"));
info2.add(info2Txt);
add(info2);
JPanel info3 = new JPanel();
info3.add(new JLabel("info3:"));
info3.add(info3Txt);
add(info3);
validate();
repaint();
}else if(b.getText().equals("Shares")){
//Dummy test text
System.out.println("Shares");
}else
//Dummy test text
System.out.println("Machine");
}
}
public static void main(String[] args){
new ChangePanel();
}
}
As you are working with BoxLayout, you should provide size hints to the PopUpPanel panel, which you haven't given.
When a BoxLayout lays out components from top to bottom, it tries to size each component at the component's preferred height. If the vertical space of the layout does not match the sum of the preferred heights, then BoxLayout tries to resize the components to fill the space. The components either grow or shrink to fill the space, with BoxLayout honoring the minimum and maximum sizes of each of the components.
check out the official tutorial page discussion: BoxLayout Feature
Call revalidate() and repaint() on the container after removing or adding components to it. So if you change the following lines:
validate();
repaint();
to:
revalidate();
repaint();
The content should appear. Though, it will not fit the original size of the JOptionPane. You can override PopUpPanel.getPreferredSize() to return desired size so that JOptionPane is packed properly, ie:
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
You can also use JDialog instead of JOptionPane.
Also, consider using CardLayout instead of swapping components manually. Check How to Use CardLayout for examples.
Why not just use setPreferredSize(new Dimension(300, 300)) in PopUpPanel constructor? Works fine for me. Good eye on revalidate and repaint.

Categories

Resources