How do i make the buttons appear under the combo box here? In other words have button 1 and button 2 right underneath the combo box?
public class GUI extends JFrame implements ListSelectionListener, ActionListener {
private JPanel myPanelA;
private JSplitPane itemPane;
public static void startWindowsGui ( ) {
SwingUtilities.invokeLater ( new Runnable ( ) {
public void run ( ) {
GUI gui = new GUI ( );
gui.setVisible ( true );
}
} );
}
public GUI() {
// Set the layout to a grid
setLayout ( new BorderLayout ( 5, 5 ) );
setTitle ( "UI " );
setSize ( 800, 600 );
setDefaultCloseOperation ( EXIT_ON_CLOSE );
setBackground ( new Color ( 15, 255, 10 ) );
addComponents ( );
}
private void addComponents ( ) {
JSplitPane mainPane = new JSplitPane ( JSplitPane.HORIZONTAL_SPLIT );
itemPane = new JSplitPane ( JSplitPane.VERTICAL_SPLIT );
mainPane.add ( PanelA ( ), JSplitPane.LEFT );
mainPane.add ( itemPane, JSplitPane.RIGHT );
mainPane.setOneTouchExpandable ( true );
itemPane.setOpaque(true);
itemPane.setBackground(new Color(0xffffffc0));
BufferedImage myPicture = null;
try {
myPicture = ImageIO.read(new File("C:/Users/Desktop/image.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
//add(picLabel);
itemPane.add(picLabel);
add ( mainPane, BorderLayout.CENTER );
}
private JPanel PanelA ( ) {
myPanelA = new JPanel ( );
myPanelA.setLayout ( new BorderLayout ( 0, 0 ) );
myPanelA.add ( buttonPanel ( ), BorderLayout.NORTH );
myPanelA.setBorder ( new EmptyBorder ( 0, 0, 0, 0 ) );
myPanelA.setBackground(new Color(0,0,0));
return myPanelA;
}
#Override
public void actionPerformed(ActionEvent e) {
}
#Override
public void valueChanged(ListSelectionEvent arg0) {
}
private JPanel buttonPanel ( ) {
// Create the panel
JPanel addButton = new JPanel ( );
JPanel cards; //a panel that uses CardLayout
String BUTTONPANEL = "Card with JButtons";
String TEXTPANEL = "Card with JTextField";
JPanel comboBoxPane = new JPanel(); //use FlowLayout
String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };
JComboBox cb = new JComboBox(comboBoxItems);
cb.setEditable(false);
//cb.addItemListener(this);
comboBoxPane.add(cb);
//Create the "cards".
JPanel card1 = new JPanel();
card1.add(new JButton("Button 1"));
card1.add(new JButton("Button 2"));
JPanel card2 = new JPanel();
card2.add(new JTextField("TextField", 10));
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);
addButton.add(comboBoxPane, BorderLayout.PAGE_START);
addButton.add(cards, BorderLayout.CENTER);
return addButton;
}
}
Use BoxLayout for the panel instead of it's default layout which is FlowLayout.
See this link: How to Use BoxLayout. In your case, BoxLayout.Y_AXIT will helps.
For example:
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
You need to arrange your layout, GridLayout is very good.
You need first to GridLayout(2, 1).
The first row will be assigned to the combo box,
and the second row for a panel with GridLayout(1, 2) for the two buttons.
setLayout(new GridLayout(2, 1));
add(comboBox);
JPanel inner = new JPanel();
inner.setLayout(new GridLayout(1, 2));
add(inner);
inner.add(button1);
inner.add(button2);
Related
I'm trying to align my JLabel at the top of the screen but it is showing at the bottom instead. It can be fixed if put some negative values in the Top-Bottom parameter in setBounds, However ! I wish to know why it's behaving like this and how it can be fixed the other way.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class T2{
private JFrame jf;
private JLabel jL;
private JButton b1, b2;
private JRadioButton jr1;
private JTextField tf1, tf2;
private Font ft;
public void run(){
//JFrame
jf = new JFrame("Program");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
jf.setLayout(null);
jf.setBounds(0,40,500,500);
//Container
Container c = jf.getContentPane();
//Font
ft = new Font("Consolas",1,25);
//JLABEL
jL = new JLabel();
jL.setText("Enter Name:");
c.add(jL);;
//Top-Bottom Positioning isn't working here..
jL.setBounds(50, 0 , 600, 600);
jL.setFont(ft);
//JTextField
tf1 = new JTextField("Type here...");
c.add(tf1);
tf1.setBounds(200, 0 , 200, 20);
}
public static void main(String args[]){
T2 obj = new T2();
obj.run();
}
}
Here's the screenshot:
LINK
Use a layout (the default BorderLayout does what you want), add the components you want to appear at the top to the layout with the constraint "NORTH", then magically it all works.
Further comments in the code.
class T2 {
private JFrame jf;
private JLabel jL;
private JButton b1, b2;
private JRadioButton jr1;
private JTextField tf1, tf2;
private Font ft;
public void run() {
//JFrame
jf = new JFrame( "Program" );
jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
// jf.setVisible( true ); // don't do this until the frame is composed
// jf.setLayout( null ); // yucky in all respects
// jf.setBounds( 0, 40, 500, 500 ); // use setSize() instead
//Container
// Container c = jf.getContentPane(); // normally you just call add()
//Font
ft = new Font( "Consolas", 1, 25 );
// Make panel first
JPanel panelNorth = new JPanel();
//JLABEL
jL = new JLabel();
jL.setText( "Enter Name:" );
jL.setFont( ft );
panelNorth.add( jL );
//Top-Bottom Positioning isn't working here..
// jL.setBounds( 50, 0, 600, 600 );
//JTextField
tf1 = new JTextField( "Type here..." );
// c.add( tf1 );
panelNorth.add( tf1 );
// tf1.setBounds( 200, 0, 200, 20 );
// now just add the panel to the "north" of the jframe border layout
jf.add( panelNorth, BorderLayout.NORTH );
// now make visible
jf.setSize( 600, 480 );
jf.setLocationRelativeTo( null );
jf.setVisible( true );
}
public static void main( String args[] ) {
// Swing is not thread safe, do on EDT
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
T2 obj = new T2();
obj.run();
}
} );
}
}
I understood the concepts behind JTabbedPane and GridBagLayout. However, when I try to use both together I fail. That is, when I use GBLayout, my other tabs (each tab having different functionality) are not showing up. Please help. Thank You.
Here is my code:
import java.awt.*;
import javax.swing.*;
public class Tryout extends JFrame {
private static final long serialVersionUID = 1L;
private JTabbedPane tabbedPane;
private JPanel panel1;
private JPanel breakfast;
public Tryout()
{
JPanel topPanel = new JPanel();
topPanel.setLayout( new BorderLayout() );
getContentPane().add( topPanel );
createPage1(); //Tab1
createPage2(); //Tab2
tabbedPane = new JTabbedPane();
tabbedPane.addTab( "Input Form", panel1 );
tabbedPane.addTab( "Breakfast", breakfast );
topPanel.add( tabbedPane, BorderLayout.CENTER );
}
public void createPage1()
{
/* Works fine when I un-comment this
panel1 = new JPanel();
panel1.setLayout(new BorderLayout());
panel1.add(new JLabel("Hi"), BorderLayout.NORTH);
*/
//Tabs not getting displayed if I add the code below with GBLayout
JPanel panel = new JPanel(new GridBagLayout());
this.getContentPane().add(panel);
JLabel label = new JLabel("Form");
JPanel tableButtonPanel = new JPanel();
tableButtonPanel.add(new JButton("Add Thing"));
tableButtonPanel.add(new JRadioButton("Delete Thing"));
tableButtonPanel.add(new JButton("Modify Thing"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(label, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
panel.add(tableButtonPanel, gbc);
}
public void createPage2()
{
breakfast = new JPanel();
breakfast.setLayout( new BorderLayout() );
breakfast.add( new JButton( "North" ), BorderLayout.NORTH );
breakfast.add( new JButton( "South" ), BorderLayout.SOUTH );
breakfast.add( new JButton( "East" ), BorderLayout.EAST );
breakfast.add( new JButton( "West" ), BorderLayout.WEST );
breakfast.add( new JButton( "Center" ), BorderLayout.CENTER );
}
public static void main(String args[]) {
Tryout ex = new Tryout();
ex.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ex.setSize(750,750);
ex.setVisible(true);
ex.setTitle( "Recipe Tracker" );
ex.setBackground( Color.gray );
}
}
The problem is that, in createPage1, you are adding a new JPanel to the JFrame:
this.getContentPane().add(panel);
which displaces topPanel (which contains the JTabbedPane) which is in the JFrame's BorderLayout.CENTER position. Therefore no JTabbedPane is appearing.
You could simply return the new JPanel that has been created and add it to your JTabbedPane:
public JPanel createPage1() {
JPanel panel = new JPanel(new GridBagLayout());
// this.getContentPane().add(panel); don't do this...
...
return panel;
}
and add:
tabbedPane.addTab("Input Form", createPage1());
I have several text areas aligned vertically. I want them to expand as more text is typed, but put a limit on how tall they'll become.
I've tried setting the max size, but that seems to be ignored. Any ideas?
_recipients = new JTextArea();
_recipients.setBorder( BorderFactory.createEtchedBorder() );
_recipients.setLineWrap( true );
_recipients.setWrapStyleWord( true );
_recipients.setMaximumSize( new Dimension( 111, 55 ) );
_subject = new JTextArea();
_subject.setBorder( BorderFactory.createEtchedBorder() );
_subject.setLineWrap( true );
_subject.setWrapStyleWord( true );
_subject.setMaximumSize( new Dimension( 111, 55 ) );
//JComponent area = LAF.Area.clear( );
JPanel area = new JPanel( new GridLayout( 1, 2, 6, 0 ) );
area.setOpaque( false );
area.add( _recipients );
area.add( _subject );
add( area, BorderLayout.CENTER );
I recieved advice that i should use a scroll pain, but that just created an uneditable area
JScrollPane pain = new JScrollPane();
pain.add( _recipients );
area.add( pain );
pain = new JScrollPane();
pain.add( _subject );
area.add( pain );
EDIT
not much more to it, but
public class TestFrame extends JFrame
{
TestFrame()
{
setSize( new DimensionUIResource( 800, 668 ) );
JPanel area = new JPanel( new FlowLayout( 0, 0, 0 ) );
Stuff thing = new Stuff();
area.add( thing );
add( area );
}
public static void main( String args[] )
{
TestFrame frame = new TestFrame();
frame.show();
}
private static class Stuff extends JComponent
{
private final JTextArea _subject;
Stuff()
{
setLayout( new BorderLayout() );
_subject = new JTextArea();
_subject.setBorder( BorderFactory.createEtchedBorder() );
_subject.setLineWrap( true );
_subject.setWrapStyleWord( true );
_subject.setSize( new Dimension( 111, 55 ) );
_subject.setMaximumSize( new Dimension( 111, 55 ) );
JPanel area = new JPanel( new GridLayout( 1, 2, 6, 0 ) );
area.setOpaque( false );
area.add( _subject );
add( area, BorderLayout.CENTER );
}
}
}
Personally, I prefer not to limit my JTextArea's size lest I prevent the user from adding as much information as needed. Again, I feel you're better off wrapping the JTextArea in a JScrollPane and limiting the JScrollPane vewport's size. This can be done explicitly or implicitly by telling the JTextArea how many rows and columns to start out with. For example:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;
public class TestPanel extends JPanel {
private static final int AREA_COUNT = 4;
public TestPanel() {
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new GridLayout(0, 1, 0, 5));
for (int i = 0; i < AREA_COUNT; i++) {
JTextArea area = new JTextArea(5, 30);
area.setLineWrap(true);
area.setWrapStyleWord(true);
JPanel wrapPanel = new JPanel(new BorderLayout());
wrapPanel.add(new JLabel("JTextArea " + i), BorderLayout.PAGE_START);
wrapPanel.add(new JScrollPane(area), BorderLayout.CENTER);
add(wrapPanel);
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("TestPanel");
frame.getContentPane().add(new TestPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
How do I make the subpanels within my main panel stay where they are when I set one of the subpanels to be invisible?
What I have looks like:
[ (Panel1) (Panel2) (Panel3) (Panel4) ]
When I do panel3.setVisible(false) it then looks like:
[ (Panel1) (Panel2) (Panel4) ]
I would like it to look like:
[ (Panel1) (Panel2) (Panel4) ]
I am using the GridBagLayout and my mainPanel declaration looks like:
final JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
and I add an new panel like:
final JTextField valueTextField = new JTextField();
valueTextField.setPreferredSize(new Dimension(80, 25));
valueTextField.setName("Value");
c.gridx =0;
panel.add(valueTextField, c);
I'll provide more code if needed and I don't care which layout I use as long as it gets me what I want.
I suggest using a CardLayout within the individual cells, and instead of setting it to invisible, switch to an empty panel instead.
The code below demonstrates this. Within hidePanel() there are two options to hide the cell with the CardLayout route currently enabled.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class InvisiblePanels {
public static void main(String... args) throws Exception {
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
frame.add(new MyPanel(), c);
c.gridx = 1;
frame.add(new MyPanel(), c);
c.gridx = 2;
frame.add(new MyPanel(), c);
frame.pack();
frame.setVisible(true);
}
private static class MyPanel extends JPanel {
CardLayout layout;
public MyPanel() {
layout = new CardLayout();
setLayout(layout);
JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
hidePanel();
}
});
add(button, "visible");
add(new JPanel(), "invisible");
layout.show(this, "visible");
}
public void hidePanel() {
// setVisible(false);
layout.show(this, "invisible");
}
}
}
I believe all the layout manager respect the visibility of a component and don't include invisible components in the preferred size and layout calculations.
One solution might be to wrap all your panels in a panel using the OverlayLayout:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OverlayLayoutInvisible
{
public static void main(String[] args)
{
JPanel panel = new JPanel();
panel.add( createPanel("Button 1") );
panel.add( createPanel("Button 2") );
panel.add( createPanel("Button 3") );
panel.add( createPanel("Button 4") );
panel.add( createPanel("Button 5") );
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( panel );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static JPanel createPanel(String text)
{
JButton button = new JButton( text );
button.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Component c = (Component)e.getSource();
c.setVisible(false);
}
});
InvisibleComponent ic = new InvisibleComponent( button );
JPanel panel = new JPanel();
panel.setLayout( new OverlayLayout(panel) );
panel.add( ic );
panel.add( button );
return panel;
}
public static class InvisibleComponent extends JComponent
{
private Component master;
public InvisibleComponent(Component master)
{
this.master = master;
setAlignmentX( master.getAlignmentX() );
setAlignmentY( master.getAlignmentY() );
}
public Dimension getPreferredSize()
{
return master.getPreferredSize();
}
}
}
You might be able to tweak GridLayout (do you have an SSCCE?)
Otherwise:
Put Panel3 and Panel4 together in a single panel that you add to the GridBagLayout. Then setup the new Panel in a Layout like FlowLayout (aligned Left with a preferred size), BorderLayout, GridLayout, etc.
I have a JPanel that encapsulates two JPanels, one on top of the other.
The first holds two JLabels which hold the playing cards.
The second holds the player's text (name and score).
However, when I remove the player's cards, the lower JPanel moves up to the top, which i would prefer that it not do. Is there a way to keep it in place regardless of whether the top JPanel is occupied or not?
Thanks
What layout managers are you using? The default layout manager for a JPanel is a FlowLayout which render child components one after the other.
Maybe you could set the root JPanel to have a BorderLayout. Then set the top JPanel to the root panel's "top" spot:
JPanel rootPanel = ...;
JPanel topPanel = ...;
rootPanel.add(topPanel, BorderLayout.TOP);
Then set a minimum size for your top JPanel:
topPanel.setMinimumSize(new Dimension(someWidth, someHeight));
And add the second panel to the bottom or middle spot:
rootPanel.add(secondPanel, BorderLayout.CENTER);
Check out http://java.sun.com/docs/books/tutorial/uiswing/layout/border.html
I had time to do an example:
public class TestJpanel extends JFrame {
public TestJpanel() {
this.setLayout( new BorderLayout() );
final JLabel card1 = new JLabel( "card1" );
final JLabel card2 = new JLabel( "card2" );
final JPanel topPanel = new JPanel();
topPanel.setPreferredSize( new Dimension( 1024, 100 ) );
topPanel.add( card1 );
topPanel.add( card2 );
this.add( topPanel, BorderLayout.NORTH );
JPanel centerPanel = new JPanel();
final JButton hideCardsButton = new JButton( "Hide cards" );
hideCardsButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
if ( topPanel.getComponentCount() == 0 ) {
topPanel.add( card1 );
topPanel.add( card2 );
hideCardsButton.setText( "Hide cards" );
} else {
topPanel.removeAll();
hideCardsButton.setText( "Show cards" );
}
topPanel.validate();
topPanel.repaint();
}
} );
centerPanel.add( hideCardsButton );
this.add( centerPanel, BorderLayout.CENTER );
}
public static void main( String[] args ) {
TestJpanel window = new TestJpanel();
window.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
window.setSize( 1024, 768 );
window.setVisible( true );
}
}
Note that this code if full of bad practices but helps demonstrate what I want with a short number of lines.