I am trying to set my JTextArea to take up the max horz length of the screen, so that the next thing, in this case a button, will start on a new line, but I have no clue how to do it. I have messed around by setting the size of the JTextArea to change from, say, 20 to 1000 but that does not do anything.
How can I get my textarea to take up the entire first row and then have the next item that I add to begin on the following row? Here is what I have so far...
MyFrame(){//constructor
super("Simple Calculator");
p = new JPanel();
grid = new GridLayout(4, 4, 3, 3);
p.setLayout(grid);
setSize(400, 500);
setResizable(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUpTextScreen();
//create buttons
for(int i = 0; i < buttonValues.length; i++){
p.add(new JButton(buttonValues[i]));
}
add(p);
setVisible(true);
}
private void setUpTextScreen() {
textOnScreen = new JTextArea(7, 1000);
textOnScreen.setText("0");//default
textOnScreen.setEditable(false);
p.add(textOnScreen);
}
How can I get my textarea to take up the entire first row and then have the next item that I add to begin on the following row?
Break your layout up into logical pieces. Start with your main panel using a BorderLayout.
First I would use a JTextField for the calculator display, not a JTextArea. Then you can add the text field using: mainPanel.add(textField, BorderLayout.PAGE_START);
Then you create a JPanel using a GridLayout for the buttons. Then you add the buttons to the button panel and use: maonPanel.add(buttonPanel, BorderLayout.CENTER);
For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
// display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
button.setPreferredSize( new Dimension(30, 30) );
buttonPanel.add( button );
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(text), text);
inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Hava a look at Nested layouts, you can add one panel with a BorderLayout (there are other options too though) and add the textarea to it. Then you only need one more panel with a GridLayout that displays the buttons. This is an example: (Note that a few lines are unnecessary in this code, but they help understand layouts)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.LineBorder;
public class Example extends JFrame {
Example() {//
super("Simple Calculator");
// The Main Panel where the 2 other panels will be on
JPanel mainPanel = new JPanel(new BorderLayout());
// The textarea will be inside this panel
JPanel areaPanel = new JPanel(new BorderLayout());
JTextArea area = new JTextArea(
"This is a JTextArea -Long text to show it works -Long text to show it works- -Long text to show it works- -Long text to show it works- -Long text to show it works- -Long text to show it works-");
area.setBorder(new LineBorder(Color.BLACK));
area.setWrapStyleWord(true);
area.setLineWrap(true);
// Fill the whole space of the panel with the area
areaPanel.add(area, BorderLayout.CENTER);
// The buttons will be inside this panel
JPanel buttonPanel = new JPanel(new GridLayout(4, 4, 3, 3));
for (int i = 0; i < 16; i++) { // Adding buttons
buttonPanel.add(new JButton("Button" + i));
}
// The textarea-panel should be on top of the main panel
mainPanel.add(areaPanel, BorderLayout.NORTH);
// The panel with the buttons should fill the remaining space
mainPanel.add(buttonPanel, BorderLayout.CENTER);
getContentPane().add(mainPanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setVisible(true);
}
public static void main(String[] args) {
new Example();
}
}
You can also use html tags like:
JButton button = new JButton("<html><b><u>T</u>wo</b><br>lines</html>");
Or in any other JComponent like you got.
So you can use <BR> tag you achieve your need.
Related
I want the buttons and textfield to go in the spaces marked red in the same layout as they are in. look at the picture to understand what I mean.
update: the buttons are in the place now, but the image wont appear on the second panel
how can I move them to there? heres my code so far
package gasindicator;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;
public class GasIndicator extends JPanel
{
private Image image;
GasIndicator()
{
try
{
image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
}
catch (IOException ioe)
{
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon(image) );
background.setLayout( new FlowLayout(FlowLayout.LEFT) );
add( background );
JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
buttonPanel.setOpaque( false );
//for (int i = 0; i < 7; i++)
{
JButton button = new JButton("Button");
JButton button1 = new JButton("Button");
JButton button2 = new JButton("Button");
JButton button3 = new JButton("Button");
JButton button4 = new JButton("Button");
JButton button5 = new JButton("Button");
button.setPreferredSize( new Dimension(160, 45) );
buttonPanel.add(button);
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
buttonPanel.add(button4);
buttonPanel.add(button5);
button.addActionListener(new Action());
}
background.add( buttonPanel );
}
static class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
JFrame frame2 = new JFrame("Museums in London");
frame2.setVisible(true);
frame2.setSize(550, 650);
JPanel panel = new JPanel();
frame2.add(panel);
Custom contentPane;
// JFrame frame = new JFrame("JTextField");
contentPane = new Custom();
frame2.setContentPane(contentPane);
}
}
private static void ShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GasIndicator());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> ShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
class Custom extends JPanel {
public BufferedImage image;
public Custom() {
try {
image = ImageIO.read(new URL
("http://www.destination360.com/europe/uk/images/s/museums.jpg"));
} catch (IOException ioe) {
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
}
public Dimension getPreferredSize() {
return (new Dimension(image.getWidth(), image.getHeight()));
}
public void paintComponent(Graphics x) {
super.paintComponent(x);
x.drawImage(image, 10, 10, this);
}
}
}
Simple example to demonstrate the concept of using a layout manager with a Border. The size of the buttons has also been tweaked to the size of the buttons in the image:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.basic.*;
import java.io.*;
import javax.imageio.*;
import java.net.*;
public class SSCCE extends JPanel
{
private Image image;
SSCCE()
{
try
{
image = ImageIO.read(new URL("http://i68.tinypic.com/2ceja8i.png"));
}
catch (IOException ioe)
{
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
setLayout( new BorderLayout() );
JLabel background = new JLabel( new ImageIcon(image) );
background.setLayout( new FlowLayout(FlowLayout.LEFT) );
add( background );
JPanel buttonPanel = new JPanel( new GridLayout(0, 3, 6, 5) );
buttonPanel.setBorder( new EmptyBorder(338, 233, 0, 0) );
buttonPanel.setOpaque( false );
for (int i = 0; i < 6; i++)
{
JButton button = new JButton("Button " + i);
button.setPreferredSize( new Dimension(160, 45) );
buttonPanel.add(button);
}
background.add( buttonPanel );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
Yes, there is still some tweaking of the values. But it is easier to adjust the location of the entire panel with one EmptyBorder and all the buttons move at the same time than it is to adjust the location of each button individually.
Note: Don't use the JLabel to display the image as the components will shift if the frame is resized. Instead use your custom panel to paint the image.
The problem here is that your panel has the standart Layoutmanager set onto it.
Try disable it with
contentPane.setLayout(null);
Then you can move the buttons around like you want with button.setBountds(x,y,w,h);
I always draw directly on the Frame, not using a custom panel like you do, but I see that there are use cases where this would be the better way.
If you write
new JFrame.getContentPane().setLayout(null);
your frame gets the default pane and still has it's layout set to null.
The difference is you can add directly to the frame instead of using a panel where you drop your stuff on.
frame.add(new Button().setBounds(x,y,w,h));
Try out this version of the code I tried to debugg:
Custom1 contentPane;
//at first create and set the frame
JFrame frame = new JFrame("Windowname goes here");
frame.setSize(1160, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//next add your custom panel
contentPane = new Custom1();
frame.setContentPane(contentPane);
//better add this to the panel instead of the frame
JTextField textfield = new JTextField(20);
frame.add(textfield);
textfield.setBackground(Color.black);
textfield.setForeground(Color.white);
//you are using 2 panels with null layout here
JPanel panel = new JPanel();
panel.setSize(frame.getHeight(),frame.getWidth()); //give the panel some bounds!
panel.setOpaque(false); //unnecesary
panel.setLayout(null);
panel.setBackground(Color.BLACK);
frame.add(panel);
JButton button = new JButton("London");
JButton button1 = new JButton("Oxford");
JButton button2 = new JButton("Cambridge");
//you seemed to not have added these before
JButton button4 = new JButton("Click");
JButton button5 = new JButton("Click");
JButton button6 = new JButton("Click");
button.setBounds(60, 400, 220, 30);
button.setBackground(Color.black);
button.setForeground(Color.WHITE);
button1.setBounds(x,y,w,h); // !!!! <------
button1.setBackground(Color.black);
button1.setForeground(Color.WHITE);
button2.setBounds(x,y,w,h); // !!!! <------
button2.setBackground(Color.black);
button2.setForeground(Color.WHITE);
button4.setBounds(80, 50, 100, 30);
button5.setBounds(x,y,w,h); // !!!! <------
button6.setBounds(x,y,w,h); // !!!! <------
panel.add(button);
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.add(button5);
panel.add(button6);
//SETVISIBLE ALWAYS GOES LAST
frame.setVisible(true);
I patched your code and wrote some comments in it.
I marked the spots where you need to set the bounds for the buttons with !!!!<----, you seemed to have made this for button4 but not for the other ones. Also you should get a better structure in your code, I don't want to insult you but I would call this "spaghetti code".
There are aswell some things that where a problem, for example you seemed to not have added the buttons at all but they where present in your picture...
Let me know if it would work or not after playing around with the bounds value and investigating for eventual mistakes in the code.
Also if you sent me the whole project I could watch over it, but better try it yourself, it won't give you anything if someone else made your work.
Good luck and happy coding ( ͡° ͜ʖ ͡°)
So, I'm brand spankin' new to programming, so thanks in advance for your help. I'm trying to put this base 2 to base 10/base 10 to base 2 calculator I have made into a GUI. For the life of me I can't figure out how to nicely format it. I'm trying to make it look like the following: The two radio buttons on top, the input textfield bellow those, the convert button bellow that, the output field bellow that, and the clear button bellow that. Any ideas on how I can accomplish this?
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.*;
#SuppressWarnings("serial")
public class GUI extends JFrame implements ActionListener
{
private JTextField input;
private JTextField output;
private JRadioButton base2Button;
private JRadioButton base10Button;
private JButton convert;
private JButton clear;
private Container canvas = getContentPane();
private Color GRAY;
public GUI()
{
this.setTitle("Base 10-2 calc");
this.setLayout(new FlowLayout(FlowLayout.LEFT));
//this.setLayout(new GridLayout(2,2));
base2Button = new JRadioButton( "Convert to base 2");
base10Button = new JRadioButton( "Convert to base 10");
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(base2Button);
radioGroup.add(base10Button);
JPanel radioButtonsPanel = new JPanel();
radioButtonsPanel.setLayout( new FlowLayout(FlowLayout.LEFT) );
radioButtonsPanel.add(base2Button);
radioButtonsPanel.add(base10Button);
canvas.add(radioButtonsPanel);
base2Button.setSelected( true );
base10Button.setSelected( true );
input = new JTextField(18);
//input = new JFormattedTextField(20);
canvas.add(input);
output = new JTextField(18);
//output = new JFormattedTextField(20);
canvas.add(output);
convert = new JButton("Convert!");
convert.addActionListener(this);
canvas.add(convert);
clear = new JButton("Clear");
clear.addActionListener(this);
canvas.add(clear);
output.setBackground(GRAY);
output.setEditable(false);
this.setSize(300, 200);
this.setVisible(true);
this.setLocation(99, 101);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
GUI app = new GUI();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void actionPerformed(ActionEvent e)
{
String s = e.getActionCommand();
if(s.equals("Convert!"))
{
String numS = input.getText();
int numI = Integer.parseInt(numS);
if(base2Button.isSelected())
{
output.setText(Integer.toBinaryString(Integer.valueOf(numI)));
}
if(base10Button.isSelected())
{
output.setText("" + Integer.valueOf(numS,2));
}
}
if(s.equals("Clear"))
{
input.setText("");
output.setText("");
}
}
}
For a simple layout, you could use a GridLayout with one column and then use a bunch of child panels with FlowLayout which align the components based on the available space in a single row. If you want more control, I'd suggest learning about the GridBagLayout manager which is a more flexible version of GridLayout.
public class ExampleGUI {
public ExampleGUI() {
init();
}
private void init() {
JFrame frame = new JFrame();
// Set the frame's layout to a GridLayout with one column
frame.setLayout(new GridLayout(0, 1));
frame.setPreferredSize(new Dimension(300, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Child panels, each with FlowLayout(), which aligns the components
// in a single row, until there's no more space
JPanel radioButtonPanel = new JPanel(new FlowLayout());
JRadioButton button1 = new JRadioButton("Option 1");
JRadioButton button2 = new JRadioButton("Option 2");
radioButtonPanel.add(button1);
radioButtonPanel.add(button2);
JPanel inputPanel = new JPanel(new FlowLayout());
JLabel inputLabel = new JLabel("Input: ");
JTextField textField1 = new JTextField(15);
inputPanel.add(inputLabel);
inputPanel.add(textField1);
JPanel convertPanel = new JPanel(new FlowLayout());
JButton convertButton = new JButton("Convert");
convertPanel.add(convertButton);
JPanel outputPanel = new JPanel(new FlowLayout());
JLabel outputLabel = new JLabel("Output: ");
JTextField textField2 = new JTextField(15);
outputPanel.add(outputLabel);
outputPanel.add(textField2);
// Add the child panels to the frame, in order, which all get placed
// in a single column
frame.add(radioButtonPanel);
frame.add(inputPanel);
frame.add(convertPanel);
frame.add(outputPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
ExampleGUI example = new ExampleGUI();
}
}
The end result:
I am having trouble finding a way to invoke an action listener that returns the value of the button clicked in the text area at the bottom.
I made the buttons using a for loop and did not expressly give the buttons a name so I do not know how to reference them when trying to incorporate an ActionListener.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class buttoner implements ActionListener {
//JFrame
JFrame frame = new JFrame("Button Game");
//Make JPanels
JPanel panelLabel = new JPanel();
JPanel buttonGrid = new JPanel(new GridLayout(0,10));
JPanel bottomPanel = new JPanel();
//JLabel
private JLabel label1 = new JLabel("The Button Game");
public buttoner() {
//set layout
frame.setLayout(new BorderLayout());
frame.add(panelLabel, BorderLayout.NORTH);
frame.add(buttonGrid, BorderLayout.CENTER);
frame.add(bottomPanel, BorderLayout.SOUTH);
//Set stuff
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,700);
frame.setVisible(true);
//Change label color
label1.setForeground(Color.RED);
//add Label
panelLabel.add(label1);
//add Buttons
for (int i = 1; i <= 60; i++) {
String val = Integer.toString(i);
buttonGrid.add(new JButton(val));
}
//Add JText Area to bottom JPanel
String num = "value";
JTextArea jta = new JTextArea(num, 1, 1);
bottomPanel.add(jta);
frame.pack();
}
public static void main(String args[]){
buttoner gui = new buttoner();
}
public void actionPerformed(ActionEvent a) {
}
}
I created an action listener to put the value in the text area at the bottom of the GUI.
I fixed a few problems with your code.
In the main method, I called the SwingUtilities invokeLater method to put the Swing GUI on the Event Dispatch thread (EDT). Swing components must be created and updated on the EDT.
The name of a Java class must start with a capital letter.
It's safer to put your Swing components on a JPanel, rather than add them directly to a JFrame.
I separated the code that creates the JFrame from the code that creates the JPanels. It should be easier for any reader of your code, including yourself, to understand what's going on.
In the createMainPanel method, I grouped the code so that everything having to do with the buttonGrid JPanel, to take one instance, is in one place in the code.
I added the action listener to the code that creates the buttonGrid JPanel.
I wrote action listener code that updates the JTextArea with the left clicked button label.
Here's the corrected code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class Buttoner implements ActionListener {
// JFrame
private JFrame frame = new JFrame("Button Game");
// Make JPanels
private JPanel panelLabel = new JPanel();
private JPanel buttonGrid = new JPanel(new GridLayout(0, 10));
private JPanel bottomPanel = new JPanel();
// JLabel
private JLabel label1 = new JLabel("The Button Game");
private JTextArea jta;
public Buttoner() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
// Change label color
label1.setForeground(Color.RED);
// add Label
panelLabel.add(label1);
panel.add(panelLabel, BorderLayout.NORTH);
// add Buttons
for (int i = 1; i <= 60; i++) {
String val = Integer.toString(i);
JButton button = new JButton(val);
button.addActionListener(this);
buttonGrid.add(button);
}
panel.add(buttonGrid, BorderLayout.CENTER);
// Add JText Area to bottom JPanel
String num = "value";
jta = new JTextArea(num, 1, 1);
jta.setEditable(false);
bottomPanel.add(jta);
panel.add(bottomPanel, BorderLayout.SOUTH);
return panel;
}
public static void main(String args[]) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new Buttoner();
}
};
SwingUtilities.invokeLater(runnable);
}
public void actionPerformed(ActionEvent a) {
JButton button = (JButton) a.getSource();
jta.setText(button.getText());
}
}
Try creating an array of buttons and add the newly created button to the array. See comments.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class buttoner implements ActionListener {
//JFrame
JFrame frame = new JFrame("Button Game");
//Make JPanels
JPanel panelLabel = new JPanel();
JPanel buttonGrid = new JPanel(new GridLayout(0,10));
JPanel bottomPanel = new JPanel();
//JLabel
private JLabel label1 = new JLabel("The Button Game");
private JButton buttons[] = new JButton[60]; //create an array of button for future reference
public buttoner() {
//set layout
frame.setLayout(new BorderLayout());
frame.add(panelLabel, BorderLayout.NORTH);
frame.add(buttonGrid, BorderLayout.CENTER);
frame.add(bottomPanel, BorderLayout.SOUTH);
//Set stuff
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,700);
frame.setVisible(true);
//Change label color
label1.setForeground(Color.RED);
//add Label
panelLabel.add(label1);
//add Buttons
for (int i = 1; i <= 60; i++) {
String val = Integer.toString(i);
JButton btn = new JButton(val);
btn.addActionListener(this); //add an actionListener right away
buttons[i] = btn; //add the button in the array for future reference
buttonGrid.add(btn);
}
//Add JText Area to bottom JPanel
String num = "value";
JTextArea jta = new JTextArea(num, 1, 1);
bottomPanel.add(jta);
frame.pack();
}
public static void main(String args[]){
buttoner gui = new buttoner();
}
public void actionPerformed(ActionEvent a) {
}
}
I'm using JSplitPane includes two JScrollPane at each side. I don't know how to make them at equals size at start up. Here is my main code:
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
inputTextArea = new JTextArea();
outputTextArea = new JTextArea();
// put two TextArea to JScrollPane so text can be scrolled when too long
JScrollPane scrollPanelLeft = new JScrollPane(inputTextArea);
JScrollPane scrollPanelRight = new JScrollPane(outputTextArea);
// put two JScrollPane into SplitPane
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
scrollPanelLeft, scrollPanelRight);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(650); // still no effect
contentPane.add(splitPane, BorderLayout.CENTER);
I have used splitPane.setDividerLocation(getWidth() / 2); but still no effect.
Please tel me how to fix this.
For more detail. Here is my full code:
package com.view;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
//import com.controller.Controller;
public class Main extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
public JTextArea inputTextArea;
public JTextArea outputTextArea;
private JButton inputBtn;
private JButton outputBtn;
private JButton sortBtn;
public JRadioButton firstButton;
public JRadioButton secondButton;
public JRadioButton thirdButton;
JSplitPane splitPane;
//Controller controller;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
// controller = new Controller(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
/**
* center
* include two TextArea for display text
*/
inputTextArea = new JTextArea();
outputTextArea = new JTextArea();
// put two TextArea to JScrollPane so text can be scrolled when too long
JScrollPane scrollPanelLeft = new JScrollPane(inputTextArea);
JScrollPane scrollPanelRight = new JScrollPane(outputTextArea);
// put two JScrollPane into SplitPane
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
scrollPanelLeft, scrollPanelRight);
splitPane.setOneTouchExpandable(true);
contentPane.add(splitPane, BorderLayout.CENTER);
/**
* Top
* Include two button : SelectFile and WriteToFile
* this layout includes some tricky thing to done work
*/
// create new input button
inputBtn = new JButton("Select File");
// declare action. when user click. will call Controller.readFile() method
// (see this method for detail)
inputBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// controller.readFile();
}
});
// create new output button
outputBtn = new JButton("Write To File");
// declare action. when user click. will call Controller.writeFile() method
// (see this method for detail)
outputBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// controller.writeFile();
}
});
// put each button into seperate panel
JPanel tmpPanel1 = new JPanel();
tmpPanel1.add(inputBtn);
JPanel tmpPanel2 = new JPanel();
tmpPanel2.add(outputBtn);
// finnally. put those two pane into TopPane
// TopPane is GridLayout
// by using this. we can sure that both two button always at center of screen like Demo
JPanel topPanel = new JPanel();
topPanel.setLayout(new GridLayout(1, 2));
topPanel.add(tmpPanel1);
topPanel.add(tmpPanel2);
contentPane.add(topPanel, BorderLayout.NORTH);
/**
* Bottom panel
* Include all radionbutton and sortbutton
*/
// Group the radio buttons.
firstButton = new JRadioButton("Last Name");
secondButton = new JRadioButton("Yards");
thirdButton = new JRadioButton("Rating");
// add those button into a group
// so . ONLY ONE button at one time can be clicked
ButtonGroup group = new ButtonGroup();
group.add(firstButton);
group.add(secondButton);
group.add(thirdButton);
// create sor button
sortBtn = new JButton("Sort QB Stats");
// add action for this button : will Call Controller.SortFile()
sortBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// controller.sortFile();
}
});
// add all to bottomPanel
JPanel bottomPanel = new JPanel(new FlowLayout());
bottomPanel.add(firstButton);
bottomPanel.add(secondButton);
bottomPanel.add(thirdButton);
bottomPanel.add(sortBtn);
contentPane.add(bottomPanel, BorderLayout.SOUTH);
setContentPane(contentPane);
setTitle("2013 College Quarterback Statistics");
setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
setVisible(true);
System.out.println("getwidth: " + getWidth());
splitPane.setDividerLocation(getWidth()/2);
}
}
Thanks :)
I got it right for you. I add this;
contentPane.add(splitPane, BorderLayout.CENTER);
splitPane.setResizeWeight(0.5); <------- here :)
And I got rid of the setDviderLocation() at the bottom
Inititally sets the resize wieght property. values are 0.0 to 1.0, a double value percentage to split the pane. There's a whole lot to exaplain about preferred sizes and such that I read about in the JSplitPane tutorial, so you can check it out for yourself.
It really depends on the exact behaviour you want for the split pane.
You can use:
splitPane.setResizeWeight(0.5f);
when you create the split pane. This affects how the space is allocated to each component when the split pane is resized. So at start up it will be 50/50. As the split pane increased in size the extra space will also be split 50/50;
splitPane.setDividerLocation(.5f);
This will only give an initial split of 50/50. As the split pane size is increased, the extra space will all go to the last component. Also, note that this method must be invoked AFTER the frame has been packed or made visible. You can wrap this statement in a SwingUtilities.invokeLater() to make sure the code is added to the end of the EDT.
Initially getWidth() size is 0. Add splitPane.setDividerLocation(getWidth()/2); after setvisible(true). Try,
// put two JScrollPane into SplitPane
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
scrollPanelLeft, scrollPanelRight);
splitPane.setOneTouchExpandable(true);
// still no effect
add(splitPane, BorderLayout.CENTER);
setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
setVisible(true);// JFrame setVisible
splitPane.setDividerLocation(getWidth()/2); //Use setDividerLocation here.
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.