import java.awt.*;
import javax.swing.*;
public class Crisis extends JFrame {
public Crisis() {
super("Crisis");
setLookAndFeel();
setSize(348, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panicButton = new JButton("Panic");
dontPanicButton = new JButton("Don't Panic");
blameButton = new JButton("Blame Others");
mediaButton = new JButton("Notify the Media");
saveButton = new JButton("Save Yourself");
JPanel pane = new JPanel();
BorderLayout moo = new BorderLayout();
pane.setLayout(moo);
pane.add(panicButton, BorderLayout.NORTH);
pane.add(dontPanicButton, BorderLayout.SOUTH);
add(pane);
FlowLayout flo = new FlowLayout(FlowLayout.CENTER,10,10);
JPanel noo = new JPanel();
noo.setLayout(flo);
noo.add(blameButton);
noo.add(mediaButton);
noo.add(saveButton);
add(noo);
setVisible(true);
}
public static void main(String[] arguments) {
new Crisis();
}
}
panicButton and dontPanicButton don't show in GUI
JFrame by default uses BorderLayout and you can add only single component in each portion north, south, west, east and center.
You are adding two component in the center and only last one will be visible.
add(pane); // Added in center
...
add(noo); // Added in center and replaced last one <<-- Here is the problem
Add it in different portion (segment) or use another layout that suits as per your need.
Read more
A Visual Guide to Layout Managers
How to Use BorderLayout
Related
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;
}
I'm trying to center an image and position text to south in a border layout.
Here's what I have so far
import java.awt.BorderLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FlowWindow extends JFrame {
public FlowWindow() {
Container contentPane = getContentPane();
JPanel PanelImage = new JPanel();
JPanel PanelText = new JPanel();
contentPane.setLayout(new FlowLayout());
This Section is where the image is supposed to be centered in the border.
//calls the image and displays it to screen
//supposed to center it also
ImageIcon imageIcon = new
ImageIcon(getClass().getResource("WITlogo.JPG"));
JLabel label = new JLabel(imageIcon);
PanelImage.add(label);
contentPane.add(PanelImage, BorderLayout.CENTER);
This section is where the text is supposed to be position south in the border.
//creates the string of text and displays to screen
//supposed to position it in the south section of the border
contentPane.add(new JLabel("Waterford Institude of technology"));
PanelText.add(label);
contentPane.add(PanelText, BorderLayout.SOUTH);
}
public static void main(String args[]) {
FlowWindow window = new FlowWindow ();
window .setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setTitle("FlowWindow ");
window.pack();
window.setVisible(true);
window .show();
}
}
The easiest way to center a component is to use a GridBagLayout:
JPanel center = new JPanel( new GridBagLayout() );
JLabel imageLabel = new JLabel(...);
center.add(image, new GridBagConstraints());
JLabel textLabel = new JLabel(...);
Then you add your components to the frame using:
add(imageLabel, BorderLayout.CENTER);
add(textLabel, BorderLayout.PAGE_END);
Im really new to this
Then start by reading the section from the Swing tutorial on Layout Managers for working examples that show the basics.
Don't forget to look at the tutorial table of contents for more information on all Swing basics.
You are using a FlowLayout and adding stuff using BorderLayout constraints (for example BorderLayout.SOUTH).
If you want an centered picture with text just below you need to have a panel inside another panel.
I want to create a two dimensional JSplitpane like design in Java swing.
Such that the JFrame will be split into 4 parts, and upper and lower parts are separated by another split, and left and right part are separated by yet another split line. Also if I click and drag any part of vertical split line, the complete line should move in dragged direction.
I am trying to achieve this, by using split pane within split pane. But then on dragging vertical split line, it only drags either components below horizontal line or above horizontal split line.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Demo extends JFrame {
int screenwidth=760,screenheigth=550;
JSplitPane top_sp,bottom_sp,main_sp;
JButton b1,b2,b3,b4,b5,b6;
JButton b7,b8,b9,b10;
MailClient(){
setSize(screenwidth,screenheigth);
setLayout(new BorderLayout());
setTitle("Demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
b1=new JButton("B1");
b2=new JButton("B2");
b3=new JButton("B3");
b4=new JButton("B4");
b5=new JButton("B5");
b6=new JButton("B6");
b7=new JButton("B7");
b8=new JButton("B8");
b9=new JButton("B9");
b10=new JButton("B10");
JPanel topleft=new JPanel(new FlowLayout());
topleft.add(b1);
topleft.add(b2);
JPanel topright=new JPanel(new FlowLayout(FlowLayout.CENTER));
topright.add(b3);
topright.add(b4);
topright.add(b5);
topright.add(b6);
JPanel bottomleft=new JPanel(new FlowLayout(FlowLayout.CENTER));
bottomleft.add(b7);
bottomleft.add(b8);
bottomleft.add(b9);
bottomleft.add(b10);
JPanel bottomright=new JPanel(new FlowLayout(FlowLayout.CENTER));
bottomright.add(new JLabel("TABLE"));
top_sp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,topleft,topright);
bottom_sp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,bottomleft,bottomright);
main_sp=new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,top_sp,bottom_sp);
add(main_sp,"Center");
setVisible(true);
}
public static void main(String args[]){
Demo demo=new Demo();
}
}
You can use a property change listener to detect when the split pane divider has been moved, and then set the location of the other split pane:
import javax.swing.*;
import java.awt.*;
public class Example extends JFrame {
public Example() {
JPanel topLeftPanel = new JPanel();
JPanel topRightPanel = new JPanel();
JPanel bottomLeftPanel = new JPanel();
JPanel bottomRightPanel = new JPanel();
JSplitPane topPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, topLeftPanel, topRightPanel);
JSplitPane bottomPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bottomLeftPanel, bottomRightPanel);
topPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, pce -> {
bottomPane.setDividerLocation((int) pce.getNewValue());
});
bottomPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, pce -> {
topPane.setDividerLocation((int) pce.getNewValue());
});
JSplitPane mainPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topPane, bottomPane);
setContentPane(mainPane);
setLocationRelativeTo(null);
setMinimumSize(new Dimension(400, 400));
setVisible(true);
}
public static void main(String[] args) {
new Example();
}
}
you have to listen to the split-change:
split.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY,
new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pce) {}
});
(see Detecting JSplitPane Divider Movement for further information)
whenever you change the size of one JSplitPane, you have to change the other as well.
split.setDividerLocation(proportionalLocation);
You can also check out the Split Pane Synchronizer.
This is a reusable class that allows you to synchronize 2 (or more) split panes. The classes uses a single PropertyChangeListener to manage the change in divider location so your application code doesn't need to keep track of each split pane separately.
No matter what I do, I can't get the JFrame to show anything. Its just blank. I added the buttons starter and tutorialer to the JPanel game and added that JPanel to the the JPanel cards which I set to a cardLayout.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class layouter extends JFrame {
public static void main (String[]args){
layouter x = new layouter();
}
public layouter(){
setSize(600,600);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Pan p = new Pan();
setContentPane(p);
setVisible(true);
}
}
class Pan extends JPanel{
JButton starter;
JButton tutorialer;
JPanel start;
JPanel tutorial;
JPanel game;
JPanel cards;
CardLayout cl;
Pan(){
starter = new JButton("start");
tutorialer = new JButton("tutorial");
start = new JPanel();
tutorial = new JPanel();
game = new JPanel();
cards = new JPanel( new CardLayout());
cl= (CardLayout)(cards.getLayout());
game.setLayout(null);
starter.setBounds(150,150,100,50);
tutorialer.setBounds(150,200,100,50);
game.add(starter);
game.add(tutorialer);
cards.add(game,"game");
add(cards);
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
cl.show(cards,"game");
System.out.println("hello");
}
}
game.setLayout(null); <-- This is going to cause you issues as anything your add to this container will no longer be automatically laid out. Components by default have a size and position of 0x0
Make use of an appropriate layout manager. See Laying Out Components Within a Container for more details.
If you add any more containers to games, you may need to "show" the default view you want to been shown first
cl.show(cards, "game");
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.