I have a class PanelTrial extends JPanel & implements GroupLayout. In it, I have a JTabbedPane namely jTabbedPane on left & another JPanel namely rightPanel on right. In rightPanel, I load 2 panels (namely compoPanel, btnsPanel) alternatively during runtime.
My Issue : Width of compoPanel, btnsPanel is different (and I want it to be different). Initially compoPanel (that is bigger in W) is loaded in the rightPanel. I am looking for is, when I load btnsPanel in rightPanel, I want the jTabbedPane's size to increase and occupy all free space. I update the PreferredSize of jTabbedPane & rightPanel - and their sizes also change. BUT location of rightPanel doesn't move to extreme right - this makes it in the middle of jTabbedPane.
Here is the code that I use :
orgTabDimen = new Dimension(350, 600);
newTabDimen = new Dimension(500, 600);
orgRghtDimen = new Dimension(280, 574);
newRghtDimen = new Dimension(50, 574);
private void updateRightPanel(boolean showBtnPanel) {
rightPanel.removeAll();
GroupLayout layout = (GroupLayout) rightPanel.getLayout();
if (showBtnPanel) {
// SHOW BTNSpANEL
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(btnPanel));
layout.setVerticalGroup(layout.createParallelGroup(
Alignment.TRAILING).addComponent(btnPanel));
// Set respective dimesions
rightPanel.setPreferredSize(newRghtDimen);
this.jTabbedPane1.setPreferredSize(newTabDimen);
} else {
// SHOW COMPOpANEL
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(compoPanel));
layout.setVerticalGroup(layout.createParallelGroup(
Alignment.TRAILING).addComponent(compoPanel));
rightPanel.setPreferredSize(orgRghtDimen);
this.jTabbedPane1.setPreferredSize(orgTabDimen);
}
jPanel1.validate();
this.validate();
}
Can anyone help me solve this issue - am stuck up here. Can't figure out a way where the btnsPanel shows up on extreme right. I even tried with calling invalidate(), but that also didn't help me.
Any help is highly appreciative.
Thanks
Related
I am writing a program that is meant to use a BorderLayout with two button on the West and East side of the window. Somehow, there is a large gap in the center. Is there any way that I can eliminate this gap and have the two buttons be tangent with each other? Below I have attached my code. Any help is appreciated :).
import java.applet.*;
import java.awt.*;
public class HON extends Applet {
Button p1;
Button p2;
BorderLayout layout;
public void init() {
layout = new BorderLayout();
setLayout(layout);
p1 = new Button("text");
p2 = new Button("text");
add(p1, BorderLayout.WEST);
add(p2, BorderLayout.EAST);
}
public void stop() {
}}
BorderLayout is doing exactly what the name implies - putting stuff on the border. This is the reason for the gap in the center. If you want to have something that has 2 buttons side by side, I would recommend the GridLayout for its simplicity. Code would go something like this:
GridLayout layout = new GridLayout(1,2); // Or (2,1), depending on how you want orientation
JPanel pane = new JPanel();
pane.setLayout(layout);
pane.add(leftButton); // Where leftButton is the JButton (or other swing component) on the left
pane.add(rightButton); // Same goes for the right JButton
// Then add your JPanel to the Frame and all that jazz below.
This should do what you want if I understand your question correctly. Notice also that I am using Swing components because they are still maintained by Java. Leave a comment/question if you need any other help with this.
EDIT: Notice in the comments that MadProgrammer suggested using the GridBagLayout. This is more powerful/versatile than plain vanilla GridLayout, but also is a bit harder to learn, so you can sort of take your pick as to which you want to do.
I am using a BorderLayout for the frame (the first one that "caught" my attention in the tuts) and a FlowLayout for the labels (the one I found appropriate for what I do), and the result shows up like this:
My objective is to push the "2*1" a little bit down, to sort of "center" it.
I looked around and found a lot of people saying to use a null layout, but then saying it's not the best alternative (even though my window is not resizable), and the other solution I found was using a combo of layouts (unless I misunderstood).
The question is the one on top of this, plus if not, what really is the best alternative? (The following is the code that makes this window (minus the vars and other methods, to simplify visualization).
public Frame() {
super("Jogo de Multiplicar!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setSize(300, 200);
setResizable(false);
getContentPane().setBackground(pink);
mensagem = new TransparentPanel();
operacao = new TransparentPanel();
//added stuff in mensagem and operacao
add(operacao);
add(mensagem, BorderLayout.SOUTH);
}
My objective is to push the "2*1" a little bit down, to sort of "center" it.
If you just want more space at the top then you can use a Border:
operacao.setBorder( new EmptyBorder(...) );
Read the section from the Swing tutorial on How to Use Borders for more information.
If you want to actually center it you can use a BoxLayout:
Box box = Box.createVerticalBox();
box.add( Box.createVerticalGlue() );
box.add( topPanel );
box.add( Box.createVerticalGlue() );
box.add( bottomPanel );
The tutorial also has a section on How to Use BoxLayout. Search the table of contents.
You could use MigLayout as your only LayoutManager. It's pretty mighty and usually offers everything that the other managers do too.
With this it's pretty simple to center the components:
public class MultiplyExample extends JFrame{
private static final long serialVersionUID = 1L;
JLabel testLabel = new JLabel("2*2 = 4");
public MultiplyExample(){
super("Example");
setBounds(300, 50, 200, 200);
// Set the MigLayout, so that columns and then rows get centered
setLayout(new MigLayout("center, center"));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(testLabel);
}
public static void main(String[] args) {
JFrame testFrame = new MultiplyExample();
testFrame.setVisible(true);
}
}
Result:
Here is a demo what the MigLayout has to offer:
http://www.miglayout.com/swingdemoapp.jnlp
Here is a quickstart-guide:
http://www.miglayout.com/QuickStart.pdf
If you have to use BorderLayout, you could put your components onto another panel and put this one into the center by using BorderLayout.CENTER:
pane.add(button, BorderLayout.CENTER);
I am new to Swing. I am building a JFrame with a JScrollPane inside it using Eclipse IDE. Inside of the JScrollPane is a JPanel in Border Layout. I tried to add a JButton (called "submitAnswers") to the JFrame using the code below, but for some reason the button only appears at the end of the frame on my computer, but not on other computers (my friend tried it on his Mac and I tried it on a separate Windows OS like mine). Some proposed solutions that I have tried and from other sites that have not worked include:
Use the pack() method. Reason: since the preferred size of the JPanel is much longer in height than the JFrame (hence I employed a JScrollPane), packing the JFrame only causes the text to be not visible on the desktop.
Place button on content JPanel. Reason: I don't know. It just wouldn't appear on another desktop computer or my friend's mac computer.
Use BorderLayout.SOUTH instead of BorderLayout.PAGE_END. Reason: There was absolutely no change. The button would still be visible on my computer, but invisible on others.
Place button directly on JFrame. Reason: I don't know.
In addition, my JFrame is nested within a static method; hence, I've only included the relevant code for the specific method I'm having issues with.
Has anyone had this issue before? I would really appreciate your insight.
Code:
public static void createTestPage() {
JFrame testFrame = new JFrame("testing...1,2,3");
//Customizes icon to replace java icon
try {
testFrame.setIconImage(ImageIO.read(new File("src/icon.png")));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//Centers location of introFrame to center of desktop
Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
testFrame.setLocation(screenDimensions.width / 16,screenDimensions.height / 14);
//Size and display the introFrame.
Insets insets = testFrame.getInsets();
//Format size of screen itself
testFrame.setSize(1200 + insets.left + insets.right,
400 + insets.top + 250 + insets.bottom);
//Temporarily set screen so that it cannot be resized
testFrame.setResizable(false);
//Set background color of testFrame
testFrame.getContentPane().setBackground(new Color(75, 0, 130));
testFrame.setLayout(new BorderLayout());
//Set layout of testFrame
testFrame.setLayout(new BorderLayout(10, 1));
//Test content
JPanel testContentPanel = new JPanel();
testContentPanel.setBackground(new Color(75, 0, 130));
testContentPanel.setSize(new Dimension(900,2060));
testContentPanel.setPreferredSize(new Dimension(900, 2060));
//Test content pane layout
testContentPanel.setLayout(new BoxLayout(testContentPanel, BoxLayout.PAGE_AXIS));
//Create panel to hold instructions text
JPanel instructionsPanel = new JPanel();
instructionsPanel.setBackground(new Color(75, 0, 130));
instructionsPanel.setLayout(new BorderLayout(10,1));
//Create JPanel for submit answers button
JPanel submitAnswersPanel = new JPanel(new BorderLayout());
submitAnswersPanel.setBackground(new Color(75, 0, 130));
submitAnswersPanel.setVisible(true);
//Create button to submit personality test answers
JButton submitAnswers = new JButton("Submit Answers");
submitAnswers.setVisible(true);
submitAnswers.setBorder(new EmptyBorder(10, 400, 10, 400));
//Add submitAnswers button to panel
submitAnswersPanel.add(submitAnswers);
//Add submitAnswersPanel to test content panel
testContentPanel.add(submitAnswersPanel);
//Create scroll pane to allow for scrollable test (contents cannot fit one page)
JScrollPane testScrollPane = new JScrollPane();
testScrollPane.setViewportView(testContentPanel);
//Get rid of horizontal scroll bar and add vertical scrollbar
testScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
testScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Speed up scrolling
testScrollPane.getVerticalScrollBar().setUnitIncrement(16);
testFrame.add(testScrollPane);
//Experiment to show button
testFrame.setVisible(true);
}
I've refactored your code a little to use method to create the individual components of the GUI. You can find the full code at this ideone link
What I saw when I first copied your code to my machine was that the only thing visible was the button. So I create all the components in their own methods and then added them to the frame and panels using the Border Layout. This then enabled me to put the instructions in the NORTH sections, the button in the SOUTH section and then the main bits would go in the CENTER section.
One thing to note about the sections: (From the documentation)
The components are laid out according to their preferred sizes and the constraints of the container's size. The NORTH and SOUTH components may be stretched horizontally; the EAST and WEST components may be stretched vertically; the CENTER component may stretch both horizontally and vertically to fill any space left over.
So you should add the component you want to scale in size to the CENTER section.
My main method now looks like this:
public static void main(final String[] args) {
final JButton submitAnswers = createSubmitAnswersButton();
final JPanel instructionsPanel = createInstructionsPanel();
final JPanel testContentPanel = createContentPanel();
testContentPanel.add(instructionsPanel, BorderLayout.NORTH);
testContentPanel.add(submitAnswers, BorderLayout.SOUTH);
final JScrollPane scrollingContentPane = createScrollPaneFor(testContentPanel);
final JFrame testFrame = createJFrame();
testFrame.add(scrollingContentPane, BorderLayout.CENTER);
testFrame.setVisible(true);
}
I am a newbie, I have a question. I am trying to use Eclipse to write a Java windows application, in which I will have a main window, which will contain several things, like a dashboard sort of thing, and it will have buttons, for example to add a record to a database, and this button when pressed, will open a new relevant window on top.
I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?
Can you suggest me better ideas for a design than what I specified ?
Thank you
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.getContentPane().add(button);
jfrm.setVisible(true);
}
Add a layout to the JFrame first. For example FlowLayout:
jfrm.setLayout(new FlowLayout());
"I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?"
The reason the button stretches is because JFrame has a default BorderLayout that does not respect the preferred sizes of child components.
The solution is to set the Layout Manager to layout that does respect preferred sizes. The image blow from this example shows the most common Layout Managers and show visually which one respect the preferred size of child components.
Also, the BorderLayout is also the reason your JLabel does not show. By default, every component that is added to a BorderLayout without a position specified e.g. BorderLayout.SOUTH, will automatically be placed in the BorderLayout.CENTER position. Each position may only have one component. So when you add the JLabel it goes to the CENTER, but when you add the JButton, it also goes the CENTER, kicking out the JLabel.
If you've never encountered Layout Managers, this is probably all confusing to you. You should take the time to go over How to Layout Components Within a Container
You need to use some form of layoutmanager, you can use this information: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
You must use Layout manager.
Use this code..
public static void main(String[] args)
{
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.add(button);
jfrm.setVisible(true);
jfrm.setLayout(new FlowLayout());
jfrm.pack();
you forgot to add pack(). so use this code to get Jlabel and JButtion side by side.
Thanks...
I have a JFrame that contains two nested JSplitPanes. I want them to be set to an exact proportion on startup.
I can not use setDividerLocation(int) as I don't know the frame's size yet (I maximize it on startup). So, I use the proportional version, setDividerLocation(double).
Code:
// ...
JSplitPane left = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JSplitPane right = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
right.setResizeWeight(1); // So that I can move the dividers independently
left.setLeftComponent(scrollPane1);
right.setLeftComponent(scrollPane2);
right.setRightComponent(scrollPane3);
left.setRightComponent(right);
add(left, BorderLayout.CENTER);
add(statusLabel, BorderLayout.PAGE_END);
setVisible(true);
setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
left.setDividerLocation(0.3);
right.setDividerLocation(0.7);
// ...
Now, sometimes this works perfectly fine, but sometimes it doesn't change the dividers. I believe this is because the frame is not loaded on screen. From the setDividerLocation(double) docs:
If the split pane is not correctly realized and on screen, this method will have no effect (new divider location will become (current size * proportionalLocation) which is 0).
Is there a way to wait until the frame is "on screen"? This is probably about a few milliseconds, but it still breaks the layout on startup. I would not like to use Thread.sleep with a fixed value but some way that works with Swing.
EDIT: I tried the hack Behe suggested. It did not work, so it might not be about the timing.
EDIT 2: I debugged some more. It appears that this is caused by my resize weight being set to 1. However this is required by my layout.
I found a way. I added a ComponentListener to the inner JSplitPane that notifies me when it is resized by the frame maximizing. When that happens I can then safely set the resize weight.
final JSplitPane left = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
final JSplitPane right = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left.setDividerLocation(0.3);
right.setDividerLocation(0.3);
left.setLeftComponent(scrollPane1);
right.setLeftComponent(scrollPane2);
right.setRightComponent(scrollPane3);
left.setRightComponent(right);
add(left, BorderLayout.CENTER);
add(status, BorderLayout.PAGE_END);
setVisible(true);
right.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
right.setResizeWeight(1);
}
});
setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);