JPanel on a JPanel in a JFrame will not show - java

Hello
I'm an amateur trying to learn/improve my understanding of Java by writing a score card for archery. I ‘m trying to produce a GUI and so far have successfully produced on a JPanel a row of 18 labels of differing sizes and colours suitable for scoring a dozen.
I then tried to add five of these 'labels panels' to another panel to build up a grid and save having to create and add as many as 150 labels in some cases . No success so far as the original labels panels will not show up. All the panels are displayed on a JFrame
I've tried a number of different ways of getting the code to work, using the Java tutorial and googling the internet and studying similar problems on this site but I'm going round in circles. I must have missed something somewhere and hope that you may be able to help.
I'm using Java 6 and JGrasp v1.8.8_01 as an IDE
The following code for the labels panel has been cut down as much of it is repetitive.
import javax.swing.*;
import java.awt.*;
public class ArrowScoreLabels extends JPanel{
public JPanel createContentPane(){
JPanel panelForLabels = new JPanel();
panelForLabels.setLayout(null);
//Code creates 18 labels, sets the size, position, background colours, border and
//font and adds the labels to the’panelForLabels
JLabel scorelabel1;
scorelabel1 = new JLabel("",JLabel.CENTER);
scorelabel1.setBorder(BorderFactory.createLineBorder(Color.black));
scorelabel1.setFont(new Font("Arial", Font.ITALIC, 26));
scorelabel1.setLocation(0, 0);//first value differs for each label
scorelabel1.setSize(35, 35);
scorelabel1.setOpaque(true);
panelForLabels.add(scorelabel1);
panelForLabels.setOpaque(true);
return panelForLabels;
}
}
Running the following class shows the 18 labels on panel
import javax.swing.*;
import java.awt.*;
public class TestArrowScoreLabels {
private static void createAndShowArrowLabels() {
//Create and set up the window.
JFrame frame = new JFrame("To score one dozen");
//Create and set up the content pane.
ArrowScoreLabels asl = new ArrowScoreLabels();
frame.setContentPane(asl.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(676, 73);
frame.setVisible(true);
}
//Main method to show the GUI/
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
createAndShowArrowLabels();
}
});
}
}
The following code for the second panel is similar, compiles but only shows the second green JPanel and not the panel with the labels.
import javax.swing.*;
import java.awt.*;
public class FiveDozenScorePanel{
public JPanel createContentPane(){
//A bottom JPanel on which to place five dozenpanels.
JPanel fivedozenpanel = new JPanel();
fivedozenpanel.setLayout(null); //requires absolute spacing
fivedozenpanel.setSize(676,185);
fivedozenpanel.setBackground(Color.green);
//Label panels for five dozen
ArrowScoreLabels dozenscorepanel1, dozenscorepanel2,
dozenscorepanel3,dozenscorepanel4,dozenscorepanel5;
//Create the 5 dozenscorelabels.
dozenscorepanel1 = new ArrowScoreLabels();
dozenscorepanel1.setLocation(5,5);//y value changes for each panel
fivedozenpanel.add(dozenscorepanel1);//plus the other 4
fivedozenpanel.setOpaque(true);
return fivedozenpanel;
}
private static void createAndShowDozenPanels() {
JFrame frame = new JFrame("To score five dozen");
FiveDozenScorePanel fdsp = new FiveDozenScorePanel();
frame.setContentPane(fdsp.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window
frame.setSize(700, 233);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
createAndShowDozenPanels();
}
});
}
}
I've also tried frame.getContentPane().add(fdsp); - frame.pack(); and read so much about paint methods that I'm totally confused.
I can get the ArrowScoreLabels image to appear directly onto a JFrame rather than a JPanel but only one of them and not five.
I would appreciate being pointed in the right direction. Thankyou for your time.
Update - 14th Dec 2010
I have managed to display the panelForLabels Jpanel on another Jpanel on a JFrame. This was done by adding the following code to the class ArrowScoreLabels. The original createContentPane() method was renamed createRowOne(). The panelForLabels was coloured red and the fivedozen panel yellow to ascertain which was showing. However I was only able to persuade the programme to display one row of labels despite a great deal of experimentation and research.
public static JPanel createContentPane(){
//Bottom panelto hold rows of labels
JPanel fivedozenscorepanel = new JPanel();
fivedozenscorepanel.setLayout(null);//requires absolute spacing
fivedozenscorepanel.setSize(660,180);
fivedozenscorepanel.setBackground(Color.yellow);
fivedozenscorepanel.add(createRowOne());
fivedozenscorepanel.setOpaque(true);
return fivedozenscorepanel;
}
The only way I displayed the 5 rows of 18 labels was to create all 90 in the ArrowScoreLabels class and then add them to one JPanel using absolute spacing and then to a JFrame.
I've taken note of pstantons advice - thankyou for that - and I'm looking into using the MigLayout Manager.

simple answer: use a layout manager. don't use absolute positioning.
just comment out all of your calls to setLocation and setLayout and swing will use the default FlowLayout.
for more control over the display, use a different layout manager.
also, if you use multiple panels you will have trouble aligning things in different panels unless they contain the same number of components which are exactly the same size so consider using one panel for all of the labels.
you can achieve just about any layout you need using MigLayout.
EDIT: in your example, there's no need for ArrowScoreLabels need to extend JPanel since you are doing the work in createContentPane to construct a separate JPanel. later in your code you call new ArrowScoreLabels() wich will just return a blank JPanel, instead you need to call new ArrowScoreLabels().createContentPane()
if you want ArrowScoreLabels to extend JPanel, implement public ArrowScoreLabels() ie the constructor instead of createContentPane.

I've the impression you don't set a size to your dozenscorepanel1. So, set a size :-)
Be careful with the layout null, because it's a pain ; you always forget something. Write your own, or use an existing one.

Related

Setting Background of a JTextPane leads to visual artifacts (Java)

this is my first question on stackoverflow so pls don't be so hard with me (and my English), I'll try my best asking a good question.
The problem is about what the title suggests -> setting the background of a JTextpane (specifically setting it transparent). As the setBackground-method takes a color argument, the way i went was with an alpha value = 0. This leads to the following visual artifacts:
example picture of the visual artifacts when running the code below
I will describe it in detail now, say what i've already tried and then post a minimal example for everyone to be able to recreate the bug easily.
I have a JFrame (myFrame) holding a JPanel (Test()) in which i paint. The background of this JPanel is set to green as you can see in the code. I did this to differ between the background of the TextPane and the actual background of the panel.
We also have a JTextPane inputfield -> which takes user input (it displays what you write). This is held by a JScrollPane scrollpane.
So the Target (meaning what i try to achieve): is a User input field, which is transparent, but still displays the text the user puts in. I tried to achieve this by setting the background of the inputfield and the scrollpane to a transparent color.
I would really appreciate it, if you don't just type something like (you need to setOpague(false) for ....) if you don't know exactly what you're talking about, because i nearly tried everything i can think of and read every post i could find in the internet about the problem. I will post some of them at the end. So...
What i already tried:
The usual way i found while searching for something like "How to make TextPane transparent" was to setOpague(false) at itself as well as the scrollpane and the viewport of the scrollpane. 1. Reading about what the method actually does i don't think that is a proper solution. 2. setting Opague(false) on these three leads to everything being invisible so, that's not good. Packing the frame again after setting the background. Either nothing was fixed or the components became completely invisible.
I also tried: setBackground(null), setting the Background of just the inputfield (just every single component and every possible combination amongst the three (scrollpane, viewport, inputfield)), mixing setOpague(true)/setOpague(false)/setBackground(...) in every way i could think of. Overriding the paintComponent method of the textpane and scrollpane seemed like a good approach, but i did not come very far with it.
So here is the code:
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
#Override
public void paint(Graphics g) {
super.paint(g);
inputField.setBounds(10,10,100,100);
scrollpane.setBounds(10,10,100,100);
}
public Test(){
this.setOpaque(true);
this.setBackground(Color.GREEN);
inputField.setBounds(10,10,100,100);
scrollpane.setBounds(10,10,100,100);
inputField.setBackground(new Color(0,0,0,0));
scrollpane.setBackground(new Color(0,0,0,0));
scrollpane.getViewport().setBackground(new Color(0,0,0,0));
this.add(scrollpane);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.pack();
myFrame.setSize(640,480);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.setVisible(true);
}
}
And here some links to posts I read which describe similar problems:
Java - Transparent JScrollPane
Transparent JEditorPane in a JScrollPane over a background JPanel
setOpaque(true/false); Java
I would really appreciate if someone can help me with the problem or even only suggest me an alternative solution. I'm writing a little chat-program atm for a project for my university and i think transparent message fields are a neat idea. I will try to answer here as fast as i can. Thx in advance.
Do not use transparent color as background - kind of hard to delete with it (e.g. when component is being repaint (and opaque)).
Do not use setBounds (unless using null LayoutManager). In below example I used setPreferredSize but still better to correctly use LayoutManager (I am a bit lazy, and lot of work to do at the moment).
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
public Test(){
this.setOpaque(true);
this.setBackground(Color.GREEN);
inputField.setPreferredSize(new Dimension(300, 100));
inputField.setOpaque(false);
scrollpane.setOpaque(false);
scrollpane.getViewport().setOpaque(false);
this.add(scrollpane);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.pack();
myFrame.setVisible(true);
}
}
The whole code of main should be called on the EDT (e.g. SwingUtilities.invokeLater) since it is manipulating swing components but that is not part of the question (and not that relevant here since setVisible is the last command - components not being displayed while changed).
Your program gave me some errors when launching, occasionally. Make sure to run a swing GUI from the EDT (invokeLater()).
The line that is causing your issue is:
scrollpane.getViewport().setBackground(new Color(0,0,0,0));
Also - is there some reason you are setting bounds manually instead of using a layout manager?
Maybe I didn't understand your question, or you want to have an image in the background - but could you not just set the color of your text area to be the same color as your JPanel?
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
public Test(){
this.setBackground(Color.GREEN);
scrollpane.setPreferredSize(new Dimension(300, 300));
inputField.setBackground(Color.GREEN);
this.add(scrollpane);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.pack();
myFrame.setVisible(true);
}
});
}
}

JTextBox and all following JComponents don't show up

I want do design a simple login format and in order to do so I want two JTextFields for Username/Password and a Login Button. The Login button is display as expected but when I add the JTextField, nothing shows in my JFrame. Would be nice if someone could help a beginner out...
Here's my code (I know it's ugly but this is just a "code sketch"):
package bucketlistpackage;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GameFrame extends JFrame {
public GameFrame(String title) {
super(title); //sets title of frame
startFrame(); //sets details of main frame
final Container logincont = getContentPane(); //creates content pane
JFrame loginframe = new JFrame();
usernameField(loginframe);
loginButton(loginframe);
logincont.add(loginframe);
}
private void usernameField(JFrame loginframe) {
JTextField usernameF = new JTextField("Username", 1);
usernameF.setBounds(50, 50, 50, 20);
loginframe.add(usernameF);
usernameF.setVisible(true);
}
private void startFrame() {
this.setSize(1000, 1000);
this.setVisible(true);
}
private void loginButton(Container cont) {
JButton loginB = new loginButton();
loginB.setSize(300, 150);
loginB.setText("Login");
cont.add(loginB);
}
}
The problem lies on how you are adding component to one another in your case.
You are adding a JFrame to a Container, when in all case it should be the other way around.
The other problem is that you are not using Layouts to manage the components positions on the JFrame.
Another problem as well is that you are not refreshing the windows after adding all the stuff on it.
A bit of a resume on how Java works with native UIs:
Java creates a new thread for the UI. So if you open the debugger you will see AWT threads as well as the main threads and others. This means that you have to manage this in a correct way, because after the application starts SWING and the functions you determine for reactions will lay the ground on how it will behave. Your main thread will die, but the visual threads will keep active.
If you are just starting to program I would encourage you to practice a bit more native java language before moving to SWING or AWT. This libraries can be really painful and tricky to use.
The other thing is SWING library follows a hierarchy for the components:
JFrame > JPanels > Components
In your code you have already worked with all of them but in a disorganized way. JFrame is the main application window, where the graphics will be displayed (can also be a Canvas or whatever class you want to use for that matter). JPanels are organizers, you can use different layouts to organize whatever is inside it. And finally the Components are well... everything! A component can be a JTextField, but it can also be a JPanel, or JButton.
The idea with SWING is to create multiple Panels and organize the end components inside them, using the help of the different layouts to see whats the best approach to make them attractive in many different window sizes.
Finally, if you are using Eclipse, there is a plugin called WindowBuilder which might help you. I don't recommend you using it if you are very new to Java since it will make you depend a lot on it instead of learning how to actually code with SWING.
Hope this helps!!!
Btw, to fix the code above I would do something like this:
public GameFrame(String title) {
super(title); //sets title of frame
startFrame(); //sets details of main frame
final Container logincont = getContentPane(); //creates content pane
logincont.setLayout(new BorderLayout());
usernameField(logincont, BorderLayout.NORTH);
loginButton(logincont, BorderLayout.CENTER);
this.revalidate();
this.repaint();
}
private void usernameField(Container loginframe, String direction) {
JTextField usernameF = new JTextField("Username");
// usernameF.setBounds(50, 50, 50, 20);
loginframe.add(usernameF, direction);
usernameF.setVisible(true);
}
private void startFrame() {
this.setSize(1000, 1000);
this.setVisible(true);
}
private void loginButton(Container cont, String direction) {
JButton loginB = new JButton();
loginB.setSize(300, 150);
loginB.setText("Login");
cont.add(loginB, direction);
}

How to make a Jframe containing a Jpanel scrollable?

So I have this JFrame that contains a JPanel and in there I add JLabels with information I want but since I'll be adding labels all the time at some point the text is too long to appear so I want to add a scrollbar. Basically I want to make my JFrame with a JPanel in it scrollable. I have this code but my problem is that even though the scrollbar appears but it doesnt move and doesn't really work when the text is a lot, meaning the text still gets cut out and the scrollbar is there not moving. Does anyone know how to fix this?
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class Bar {
JFrame info = new JFrame("Information");
JLabel ballinf = new JLabel();
JPanel contentPane = new JPanel();
JScrollPane scrolling = new JScrollPane();
public Bar(){
contentPane.setOpaque(true);
contentPane.setBackground(Color.WHITE);
contentPane.setLayout(null);
scrolling = new JScrollPane(contentPane,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
info.add(scrolling);
info.setSize(750, 600);
info.setLocationByPlatform(true);
info.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
info.setVisible(true);
}
public void adding(int pos){
ballinf = new JLabel("Something ",JLabel.CENTER);//assume the text will be bigger here and have more info
ballinf.setSize(700, 30);
ballinf.setForeground(Color.green);
ballinf.setLocation(5, 5+pos);
contentPane.add(ballinf);
info.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
info.setVisible(true);
}
public static void main(String[] args){
Bar stats = new Bar();
stats.adding(0);
stats.adding(20);//this will be done in a for loop for more than 2 times so the text ends up to be a lot
}
}
contentPane.setLayout(null);
Don't use a null layout!!!
You need to use an appropriate layout manager. Read the section from the Swing tutorial on Layout Managers for more information and working examples. The layout manager will then determine the preferred size of the panel as you add components to the panel.
The scrollpane will then display the scrollbars when necessary.
If you dynamically add components to the panel (after the GUI is visible) then the code should be something like:
panel.add(...);
panel.revalidate();
panel.repaint();

How to reset or refresh Jframe with new values

I have a Jframe that the user enters new information through a Joptionpane, it is added to an array which is then appended and displayed to a contentpane.. the cycle then repeats till the user enters "STOP". Currently the program is outputting the new array under the old one. How would I clear away the old array in the content pane and only display the new values?
import java.awt.*;
import java.util.LinkedList;
import java.util.List;
public class Project1GUI {
static JFrame Frame;
static TextArea unsorted_words, sorted_words, linked_words;
public Project1GUI(String title){
//All this does is make an empty GUI FRAME.
Frame=new JFrame();//i made a new variable from the JFrame class
Frame.setSize(400,400);//Used the Variable from JFrame and used some of it functions. This function sets the hieght and width of the Frame
Frame.setLocation(200,200);//This sets where the Empty Frame should be
Frame.setTitle(title);//This puts a title up top of the Frame
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//places an x box that closes when clicked on
Frame.setVisible(true);//This activates the JFram when is set true.
Frame.setLayout(new GridLayout(1,2));//This sets the layout of the Frame and since i want a Grid i used a GirdLayout
//Functions and placed it inside the setlayout functions. to get 2 grids i places 1 meaning 1 row and 2 for 2 cols
unsorted_words=new TextArea(); //From the TextArea class i made three variables
sorted_words= new TextArea();
linked_words= new TextArea();
Container panel=new Container();
panel=Frame.getContentPane();
panel.add(unsorted_words);
panel.add(sorted_words);
panel.add(linked_words);
}
public void add_unsorted(String words){
unsorted_words.append(words+"\n");//add words to GUI
}
public void add_sorted(String words){
sorted_words.append(words+"\n");
}
public void add_linked(List<String> linked_words2){
linked_words.append(linked_words2+"\n");
}
}
For a more definitive answer, post an MCVE
Seeing as you haven't posted any code, I'm guessing you are using a JLabel or a JList or something of that sort to display the array. No matter which one you are doing, you need to tell the component to update it's content, it doesn't just do it itself. To do that, you need to call the components .setText() or similar method.
If you have a JLabel or JTextArea it could look like this.
labelOrTextArea.setText("New Text");
If you are using a JList you should update the lists Default List Model like this
dlm.addElement("New Text");
UPDATE
I see a couple things wrong with your code. First off JFrame Frame = new JFrame conventionally, variables should start with a lower case letter and they should not contain underscores '_'. You are also using AWT Components instead of Swing components. You should be using the likes of JTextArea, JPanel (Theres no JContainer), JLabel etc.
You are also never adding the panel to the frame.
frame.add(panel);
You should also not be adding stuff to the frame or panels after you set its visibility to true. So you should setup your frame like this
import javax.swing.*;
import java.awt.*;
import java.util.List;
public class Project1GUI
{
JTextArea unsorted_words, sorted_words, linked_words;
public Project1GUI()
{
JFrame frame = new JFrame("Title");
JPanel panel = new JPanel(new GridLayout(2, 1));
unsorted_words = new JTextArea();
sorted_words = new JTextArea();
linked_words = new JTextArea();
panel.add(unsorted_words);
panel.add(sorted_words);
panel.add(linked_words);
frame.add(panel);
frame.setSize(400,400);
frame.setLocation(200,200);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
You can then implement the methods you currently have and call them in an ActionListener or such.
Result:
On top of all of that, you should not rely on the use of static as it takes away from the main points of OOP.

Using Java pack() method

I can't make the pack() method work. I tried several things. My code looks like this at the moment:
Class 1:
public static void main( String[] args )
{
java.awt.EventQueue.invokeLater(new Runnable() {
public void run()
{
JavaGui mygui = new JavaGui();
// mygui.setSize(1154, 753);
mygui.setVisible(true);
mygui.pack();
Class 2:
public class JavaGui extends javax.swing.JFrame
{
public JavaGui()
{
getContentPane().setLayout(null);
..
getContentPane().add(panelLeft);
...
getContentPane().add(panelRight);
I tried putting the pack method in everywhere, but it's not going to work with this way of adding gui elements. Any suggestions why? I also tried adding everything to a JFrame instead of the getContentPane(), but I can't make that work either.
Don't use null layouts together with pack(). The pack method tells the layout managers and components to size themselves optimally, and if you instead use null layouts, then the gui risks shrinking to a minimal size, since there is no layout to hold it together.
Don't use null layouts at all for the most part. Using these risk your creating rigid GUI's that are almost impossible to extend, improve, debug.
Don't use setSize(...) and pack(). The layouts mostly respect the preferred sizes of components, not their sizes.
Instead:
Use a pleasing and sensible combination of nested JPanels, each using its own layout manager.
Let the components and the layout managers size themselves.
Then pack should help.
The general order that I do is to add all components to the GUI, then call pack(), then setLocationByPlatform(true) (I think), then setVisible(true).
For better help, please check out the Swing Layout Manager Tutorials.
Here are a couple examples to other questions on this site that use various layout managers:
A combination of BorderLayout and GridLayout to create a calculator
BorderLayout and BoxLayout Combination for labels and JTextFields
Using GridBagLayout to create flexible label/textfield grid
I would recommened beginners on building up swing guis to use a good ide with a builtin gui designer like eclipse and windowbuilder or netbeans with matisse. It will help you building up a prototype of your desired gui and gives you an insight how the layouting is done in the source code.
Experiment with the differenet layouts and what is happening when some values are changed.
one does not simply build up a well behaving gui without understanding how the layout works, so doing the recommended tutorials and looking at examples as already posted by Hovercraft Full Of Eels is absolutely necessary.
For your case i just guess what you were up to. Because youre mentioning left and right panels i suggest a JSplitPane which let you divide your screen in two areas which are customizable in size and orientation.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
public class JavaGui extends JFrame {
//SerialVersionId http://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
//Calls to Gui Code must happen on the event dispatch thread that the gui does not get stuck
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new JavaGui().setVisible(true);
}
});
}
public JavaGui() {
// Set the desired size of the frame to determine the maximum size of its components
setPreferredSize(new Dimension(1024, 768));
// Set the default close operation, if press x on frame, destroy the frame and exit the application - others are just destroy the frame or just hide the
// frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// BorderLayout because we just need a centric gui with one component, here JSplitPane in full size
getContentPane().setLayout(new BorderLayout(0, 0));
// JsplitPane is a bit special as it depends on the divider location between both panels, for the sake of a small example we take the default -1,
JSplitPane splitPane = new JSplitPane();
// 0.5 divides extra space equally to left and right component when resizing the frame - so specifiying a size for the left and right component is not
// necessary
// use the divider location default -1 to let the width of the left component decide where the right component begins, in that case because of the
// resize weight half and half
splitPane.setDividerLocation(-1);
splitPane.setResizeWeight(0.5);
getContentPane().add(splitPane, BorderLayout.CENTER);
// For the panels the same layout as default as the intention is not stated in your question
JPanel leftPanel = new JPanel();
splitPane.setLeftComponent(leftPanel);
leftPanel.setLayout(new BorderLayout(0, 0));
JPanel rightPanel = new JPanel();
splitPane.setRightComponent(rightPanel);
rightPanel.setLayout(new BorderLayout(0, 0));
// Add a button Panel to the south for doing something - flow layout for letting the components flow to the right side
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
// Close Button for closing the frame
JButton btnExit = new JButton("Destroy this frame, but let application run");
btnExit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
buttonPanel.add(btnExit);
// Set every component to its preferred size
pack();
// Make it visible
setVisible(true);
}
}
If you want your JFrame to work with a null layout, rearrange your code so that it looks like this:
public class JavaGui extends javax.swing.JFrame
{
public JavaGui()
{
setMinimumSize(1154, 753); // Make sure you do setMinimumSize() instead of setSize() when using pack() so that the JFrame does not shrink to 0 size
setLayout(null);
add(panelLeft);
add(panelRight);
pack();
}
// Next is main method
Main:
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater(new Runnable() {
public void run()
{
new JavaGui().setVisible(true);
// Do not do any formatting for your JFrame here
}
});
Before, you were modifying the JFrame after it was set visible, so that usually does not work, except for pack(). All components and settings for your JFrame should not be in the main method if you are using an anonymous inner class.
You can also use other layouts. Null layouts are for getting pixels in precise locations, which is used for advanced GUI design such as creating a custom GUI, but it seems that you are making a generic GUI with JPanels. For this, I would recommend using a GridBagLayout, which keeps everything centered if the frame is resized and is easy to use. To use a GridBagLayout, you have to replace setLayout(null); with setLayout(new GridBagLayout()); and set GridBagConstraints. Here is some example code of making a panel with a component and a GridBagLayout:
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
}
//For each component to be added to this container:
//...Create the component...
//...Set instance variables in the GridBagConstraints instance...
pane.add(theComponent, c);
// Source: Oracle Docs

Categories

Resources