Java - Set size of decorated JFrame - java

I've got a problem with the size of a JFrame:
I want to show content in the Jframe. The content will have the size 640 x 480. But I can not use the method JFrame.setSize(640, 480); because I also want to show the decoration of the window.
My first thought was: Add a panel with the preferred dimension and than use pack();. But this also doesn't work - I only get a really small window.
I think the solution to my problem could be similar to this:
String JFrame Size
How do I make a JFrame a certain size not including the border
Here is my code:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Fenster extends JFrame {
JPanel panel;
Dimension dim;
Fenster(){
dim = new Dimension(640, 480);
panel = new JPanel();
panel.setSize(dim);
panel.setMinimumSize(dim);
panel.setMaximumSize(dim);
panel.setPreferredSize(dim);
panel.setBounds(0, 0, 640, 480);
panel.setDoubleBuffered(true);
JLabel label = new JLabel("bla");
panel.add(label);
this.setLayout(null);
this.getContentPane().add(panel);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
}

this.setLayout(null); is your problem. Let the layout manager do it's job
From the JavaDocs
public void pack() Causes this Window to be sized to fit the
preferred size and layouts of its subcomponents. The resulting width
and height of the window are automatically enlarged if either of
dimensions is less than the minimum size as specified by the previous
call to the setMinimumSize method. If the window and/or its
owner are not displayable yet, both of them are made displayable
before calculating the preferred size. The Window is validated after
its size is being calculated.
Most containers (JComponent, JPanel) have a default, preferred size of 0x0, the layout manager provides this information based on the requirements of the layout manager itself and the contents of the container, but using a null, you effectivly make the container 0x0...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
add(new JLabel("Look ma, no null layouts!"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
}
}
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
See Why is it frowned upon to use a null layout in SWING? for more details...

Related

Java - My action event doesn't work

I'm learning Java and Swing, but my JButton doesn't work.
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Programma {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e){
e.printStackTrace();
}
JFrame frame = new JFrame("DIG");
JPanel panel = new JPanel();
JButton button = new JButton("Click Me");
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.setBounds(100, 100, 130, 35);
panel.add(button);
frame.add(panel);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JLabel label = new JLabel("Hello World");
label.setVisible(true);
panel.add(label);
}
});
}
}
The frame and button are visible, nut when I click it, the label doesn't appear. How can I fix this?
Do I write this before the other component like JPanel, JButton, etc., or do I write this at the end of code:
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
What is the difference ?
By the way, button.setBounds(100, 100, 130, 35) doesn't work, either.
I see some issues in your code:
button.setBounds(100, 100, 130, 35); that line will be ignored and you shouldn't be manually be determining the position of the components. See Null layout is evil and Why is it frowned upon to use a null layout in swing? altough you're not using null layout, there is explained why you shouldn't be manually determining the positions of the components.
You're running everything in your program in the main method, that will be hard to maintain later.
You're calling frame.setVisible(true) before you've added all your elements to it, that will cause you random issues.
You're not running your program on the Event Dispatch Thread (EDT), you can solve this by starting your program with the following code, which places it in the EDT. It's recommended as Swing is not thread safe.
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//Your constructor here
}
});
}
You're setting the size of the JFrame with setSize(...), instead call frame.pack() and override the getPreferredSize() method of the JPanel.
After all the above has been said, you need to call revalidate() and repaint() on your ActionListener so your program paints its new state.
This program follows all the above recommendations and produces the following outputs (before clicking and after clicking the button 3 times), I on purpose to not make the images so large, made the GUI shorter (200 x 200 instead of 400 x 400)
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Programma {
private JFrame frame;
private JPanel panel;
private JButton button;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Programma().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("DIG");
panel = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
button = new JButton("Click Me");
panel.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JLabel label = new JLabel("Hello World");
panel.add(label);
panel.revalidate();
panel.repaint();
}
});
frame.add(panel);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Do i write this before the other componente like JPanel,JButton... or do i write this at the end of code ?
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
What is the difference ?
Altough I answered this on the recommendations, the difference is that if you call setVisible before adding all your elements to the frame, then you'll find yourself with some random issues where the components are not all visible until you pass your mouse over them (or where they should be). frame.pack() and setVisible should be the last ones to be called in your program, and frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); can be at the start or the end, it doesn't affects, but I prefer to have it at the end too.
button.setBounds(100, 100, 130, 35); doesn't work too.
Well, that's because of you're using a layout manager (and that's the right way to do your GUIs) instead of a null-layout (which you shouldn't be using anyway) (See point #1).
Edit
What is the difference between frame.setSize(); and frame.setpack() ?
If you read the docs for pack():
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.
So, it will calculate the minimum size for your JFrame where all the elements are visible and in their preferred size while setSize will only set the window size, but if you place a JScrollBar inside it for example this will reduce the window size, because of that, that's why you should override the getPreferredSize(...) method of your container, so it will calculate its preferred size including the width of the JScrollBar or some other elements that could modify its size. See Should I avoid the use of setPreferred|Maximum|MinimumSize in Swing? (the general consensus says yes)
When you add components dynamically to panel, you need to repain it.
Do this
panel.revalidate();
after
panel.add(label);

Java Swing Moving Away From Null Layout

I built a great GUI using the frowned upon null layout (I defined a lot of constants and used a window resize listener to make it easy). Everything worked perfectly until I started using a new computer. Now, the component's are not positioned properly (from the picture you can see that the components are offset down and right). After researching the problem I learned that layout managers make sure that the components are positioned properly throughout different machines. Because of this, I would like to start rebuilding the GUI in an actual layout manager. The problem is that I often feel limited in the way I position components when attempting to use an actual layout manager.
For anyone who is curious, I was originally using a dell inspiron laptop with windows 10, and have moved to an Asus Laptop (I don't know the actual model, but the touch screen can detach from the keyboard), also with windows 10.
My question:
Which layout manager would be the fastest and easiest to build the GUI shown in the picture above (out of the stock Swing Layouts and others). I would like this layout to respect the components' actual sizes for only a few but not all of the components. Using this layout, how would I go about positioning the inventory button (the hammer at the bottom left) so that the bottom left corner of the inventory button is 5 pixels up and right from the bottom left corner of the container, even after resizing the container?
Thanks in advance. All help is appreciated.
EDIT: The "go find a key" and "Attempt to force the door open" options should have their sizes respected.
The simplest solution that comes to my mind is a BorderLayout for the main panel. Add the textarea to NORTH / PAGE_START. Make another BorderLayout containing the inventory button (WEST / LINE_START) and the location label (EAST / LINE_END). Add that to SOUTH / PAGE_END of the main BorderLayout. Then just add a BoxLayout with vertical alignment to the main BorderLayout's CENTER containing the two buttons. Here's a tutorial for the standard layout managers.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Example {
public Example() {
JTextArea textArea = new JTextArea("There is a locked door");
textArea.setRows(5);
textArea.setBorder(BorderFactory.createLineBorder(Color.GRAY));
textArea.setEditable(false);
WhiteButton button1 = new WhiteButton("Go find a key") {
#Override
public Dimension getMinimumSize() {
return new Dimension(200, 25);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 25);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(200, 25);
}
};
WhiteButton button2 = new WhiteButton("Attempt to force the door open");
button2.setMargin(new Insets(0, 60, 0, 60));
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
buttonPanel.add(button1);
buttonPanel.add(Box.createVerticalStrut(5));
buttonPanel.add(button2);
WhiteButton inventoryButton = new WhiteButton(
new ImageIcon(new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB)));
JLabel locationLabel = new JLabel("Location: 0");
locationLabel.setVerticalAlignment(JLabel.BOTTOM);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.add(inventoryButton, BorderLayout.WEST);
southPanel.add(locationLabel, BorderLayout.EAST);
JPanel mainPanel = new JPanel(new BorderLayout(0, 5));
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
mainPanel.add(textArea, BorderLayout.NORTH);
mainPanel.add(buttonPanel);
mainPanel.add(southPanel, BorderLayout.SOUTH);
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
private class WhiteButton extends JButton {
public WhiteButton() {
setBackground(Color.WHITE);
}
public WhiteButton(String text) {
this();
setText(text);
}
public WhiteButton(ImageIcon icon) {
this();
setIcon(icon);
setBorder(BorderFactory.createLineBorder(Color.GRAY));
}
}
}

Trouble with borders

I'm trying to get clarification as to how borders work, specifically the insets, and in searching through the Java docs and numerous websites I can't seem to find a clear explanation. Looking at this code:
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
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;
public class ShadowWindow {
public static void main(String[] args) {
new ShadowWindow();
}
public ShadowWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new ShadowPane());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShadowPane extends JPanel {
public ShadowPane() {
setLayout(new BorderLayout());
setOpaque(false);
setBackground(Color.BLACK);
setBorder(new EmptyBorder(0, 0, 10, 10));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(10, 10, getWidth(), getHeight());
g2d.dispose();
}
}
}
The way I interpret it this is what is happening:
JFrame frame (200 x 200) is created
JPanel shadowPane is created (also 200 x 200) with an empty border of 10 pixels created on the inside bottom and inside right of the JPanel
A second JPanel is created (200 x 200) and added on top of shadowPane
A rectangle is drawn (200 x 200) starting at x = 10 and y = 10
So my question in how is the shadowPane going past the range of the JFrame? Does the border go 10 pixels outside the JFrame or does it exist inside the JFrame. From everything I've found it should be inside, but that doesn't make sense based on how this code generates a shadow behind the frame. can anybody walk me through this? Thanks.
So my question in how is the shadowPane going past the range of the JFrame?
It's not. pack determines the preferred layout size of the content and makes the window big enough to accommodate it, because the frame is undercoated AND it's background is transparent, it "appears" as if the shadow hangs past the frame, it's an illusion.
The empty border is making sure that content added to the ShadowPane is "forced" into a small space.
Lets change the code slightly...
JFrame frame = new JFrame("Testing");
JPanel content = new JPanel(new BorderLayout());
content.setBackground(Color.RED);
//frame.setUndecorated(true);
//frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(content);
//frame.setContentPane(new ShadowPane());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));
ShadowPane shadowPane = new ShadowPane();
shadowPane.add(panel);
frame.add(shadowPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
What this does, is creates a new background panel, filled with the color red. It also adds the window decoration back in.
As you can see, the shadow pane and the label are are all rendered within the confines of the window.
If we once again remove the window decoration...
You can see that it's still the same...
So what's going on?
getPreferredSize is providing the core information about how the component would like to be size (in this case 200x200)
The EmptyBorder is defining a usable space within the ShadowPane which defines an area within which content can be displayed, it's leaving 10 pixels to the right and bottom of the component, in which components can't be displayed. This is take care of automatically by the layout manager. This means that the ShadowPane can actually paint here itself, but components added to it will never be displayed here, hence the shadow board.
Basically, it's smoke and mirrors and used to generate the illusion of a drop shadow behind the content added to the frame (or the ShadowPane in this case)

JScrollPane & Graphics2D

I am trying to draw graphics that is bigger than the JFrame and use JScrollPane to scroll the entire graphics. I created a simple example with two lines. The scroll bars appear but the graphics do not show.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Test extends JPanel{
public static void main(String... args) {
Test test = new Test();
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(test);
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(0, 0, 1350, 700);
JPanel contentPane = new JPanel(null);
contentPane.setPreferredSize(new Dimension(1400, 700));
contentPane.add(scrollPane);
frame.setContentPane(contentPane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.drawLine(30,30,30,3000);
g2.drawLine(30, 400, 500, 3000);
}
}
Welcome to a wonderful example of why null layouts suck...
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
Also see Why is it frowned upon to use a null layout in SWING? for more details...
The basic problem is, the JScrollPane, has a JViewport, which actually contains your component. The JViewport uses your components sizing hints to make determinations about how big it should be and the JScrollPane uses the decisions the JViewport makes to make determinations about whether it needs to display the scrollbars or not.
The JViewport is taking a look at your component and has decided, because you've not told it otherwise, that it should be 0x0 in size.
You can prove this by adding a LineBorder to your component, setBorder(new LineBorder(Color.RED));, you won't see it either (or if you do, it will be a little red square)
Start by overriding the getPrefferedSize method of the Test panel and return some appropriate size
Next, call super.paintComponent before you perform any custom painting, otherwise you'll end up with some awesome, but annoying, paint artifacts...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test extends JPanel {
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();
}
Test test = new Test();
JFrame frame = new JFrame();
JScrollPane scrollPane = new JScrollPane(test);
frame.add(scrollPane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(3000, 3000);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(30, 30, 30, 3000);
g2.drawLine(30, 400, 500, 3000);
}
}
You'll probably want to take a look at the Scrollable interface next, so you can control the default size of the JViewport, so it won't try and fill the entire screen.
Take a look at Implementing a Scrolling-Savvy Client for more details
The problem comes from the lines
JPanel panel = new JPanel();
panel.add(test);
JScrollPane scrollPane = new JScrollPane(panel);
You are adding test to panel which uses FlowLayout by default. This layout does not strech the components in it, so test on which you draw has dimensions 0x0 and what you see in the scroll pane is the empty panel.
To fix this you can set panel to use BorderLayout which stretches the center component:
JPanel panel = new JPanel(new BorderLayout());
panel.add(test);
JScrollPane scrollPane = new JScrollPane(panel);
or add test directly to the scroll pane:
JScrollPane scrollPane = new JScrollPane(test);
Additionally:
Always call super.paintComponent(g) as the first line when overriding paintComponent.
Don't use null layouts (and consequently don't set bounds on components).
When you use setPreferredSize remember that if the dimensions are too large they will "flow off" the screen.

JDesktopPane and BorderLayout

I am writing a program that attempts to simulate the evolution of a species, and it has a window that looks like this:
Originally the empty area in the bottom right was a Panel, and it is intended to draw a visual representation of the specimens, locations, and travel paths(doesn't really matter). However, you will be able to open some sort of window that allows you to create/edit different items(like species, locations, and travel paths). Originally I planned for those to simply be popup windows. But, I was thinking I would perhaps use JInternal panes for the popups, and the visual representation screen.
So in my JFrames constructor:
JDesktopPane pane = new JDesktopPane();
this.setContentPane(pane);
setLayout(new BorderLayout());//To layout the menubar, and the items on the left
panel = new GraphicsPanel(manager);
panel.setVisible(true);
And in Graphics Panel constructor:super("Graphic Project View",true,false,true,true);
This locks the Panel to BorderLayout.CENTER, and it fills up the entire space, not allowing for anything else. My guess this is because JDesktopPanes use an OverlayLayout, and when I set the layout to BorderLayout that overrides the OverlayLayout, and so my InternalFrame just gets added to the center.
So the question is:
How do I layout the things like the JMenuBar, and the left ward Panel as they are now, whilst still maintaining the capability to have JInternalFrames?
For now I am going to add the JMenuBar via JFrame.setJMenuBar(JMenuBar) instead of JFrame.add(menuBar,BorderLayout.NORTH), and then change the panel on the left into a JInternal frame, but if possible I'd rather have it as is. I would like it if I could just have the DesktopPane be added to the JFrame at BorderLayout.CENTER, and then just add the frame to the Desktop pane. If the InternalFrame were limited to that region I wouldn't care, as long as it's still mobile, ect.
EDIT: How I add JInternalFrame(Sorry it still says panel, but it has been converted to a JInternalFrame):
panel = new GraphicsPanel(manager);
panel.setSize(desktop.getSize());
panel.setLocation(0,0);
panel.setVisible(true);
desktop.add(panel);
I would start with a single JPanel (lets all it the base pane), which will house the other containers.
Using a border layout, I would add a "controls" panel to the WEST position of the base pane. Onto the CENTER position I would add the JDesktopPane.
I would set the main windows layout to BorderLayout and add the base pane to it. This will allow you to use JFrame#setJMenuBar to manage the menu bar while maintaining the result of the layout.
This will allow you to contain to use the JInternalFrames on the desktop without effecting the rest of the layout...
Simple Example
This is an overly simplified example used to demonstrate the basic concept described above...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SimpleLayout {
public static void main(String[] args) {
new SimpleLayout();
}
public SimpleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JMenuBar mb = new JMenuBar();
mb.add(new JMenu("File"));
mb.add(new JMenu("Add"));
mb.add(new JMenu("Edit"));
mb.add(new JMenu("Analize"));
mb.add(new JMenu("About"));
JFrame frame = new JFrame("Testing");
frame.setJMenuBar(mb);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new BasePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BasePane extends JPanel {
private JTextArea species;
private JTextArea locations;
private JTextArea travelPaths;
private JDesktopPane desktopPane;
public BasePane() {
setLayout(new BorderLayout());
desktopPane = new JDesktopPane();
species = new JTextArea("Species");
locations = new JTextArea("Locations");
travelPaths = new JTextArea("TravelPaths");
JPanel controls = new JPanel(new GridLayout(3, 0));
controls.add(new JScrollPane(species));
controls.add(new JScrollPane(locations));
controls.add(new JScrollPane(travelPaths));
add(controls, BorderLayout.WEST);
add(desktopPane);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Your requirements might be slightly difference, but the basic concept should get you moving.
Depending on the structure of your application, I might be tempted to separate the Controls pane into a separate class as well.

Categories

Resources