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();
}
});
}
}
Related
I'm trying to center a JButton in a JPanel using the default FlowLayout. Here is my code:
import javax.swing.*;
import java.awt.*;
public class CoinFlip {
public static void main(String[] args) {
JFrame frame = new JFrame("Coin Flip");
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton coinFlipButton = new JButton("Flip Coin");
coinFlipButton.setSize(100, 100);
JPanel coinFlipPanel = new JPanel();
coinFlipPanel.setSize(500, 100);
coinFlipPanel.setBackground(Color.GRAY);
coinFlipPanel.add(coinFlipButton);
JTextArea coinFlipResults = new JTextArea();
coinFlipResults.setSize(500, 200);
frame.getContentPane().add(coinFlipPanel);
frame.getContentPane().add(coinFlipResults);
frame.setVisible(true);
}
}
How can I center the JButton (coinFlipButton) in the JPanel (coinFlipPanel)? I've tried using FlowLayout.CENTER but that makes the button increase in size so that it takes up all the space.
I double checked with the docs and FlowLayout does have an option to center its components, so mea culpa on that. But otherwise you just kind of have to read the tutorials on the various components and their layouts, and experiment a bit.
One very important point is that jframe.getContentPane().add() for a default JFrame uses a layout that only admits one single component. If you want more than one, you have to use a second component like a JPanel with a Grid or Flow layout. By calling that method twice you're just replacing the previous component. Please go read the tutorial on JFrames and BorderLayout.
Anyway I made a quick program that does something like what you want. I added your text area to a ScrollPane because that's another way of dealing with the main content pane of a JFrame. And when I added the JPanel with the button I added it to the SOUTH part of the BorderLayout, because that's how you display more than one component with BorderLayout. (Tutorial again.)
public class JFrameBorderWithButton {
public static void main( String[] args ) {
SwingUtilities.invokeLater( JFrameBorderWithButton::newGui );
}
private static void newGui() {
JFrame frame = new JFrame();
JTextArea text = new JTextArea(5, 40);
JScrollPane scroll = new JScrollPane( text );
frame.add( scroll );
JPanel panel = new JPanel( new FlowLayout( FlowLayout.CENTER ) );
JButton button = new JButton( "Press Me" );
panel.add( button );
frame.add( panel, BorderLayout.SOUTH );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
In my experience, the simple layouts are rarely worthwhile. use something like GridBagLayout
public static void main(String [] args) throws IOException {
JFrame frame = new JFrame("Coin Flip");
JTextArea textArea = new JTextArea();
JScrollPane textScroll = new JScrollPane(textArea);
Action flipAction = new AbstractAction("Flip Coin!") {
private Random random = new Random();
#Override
public void actionPerformed(ActionEvent e) {
if (!textArea.getText().isEmpty()) {
textArea.append(System.lineSeparator());
}
if (random.nextBoolean()) {
textArea.append("Heads!");
} else {
textArea.append("Tails!");
}
}
};
JButton flipButton = new JButton(flipAction);
frame.setLayout(new GridBagLayout());
frame.setPreferredSize(new Dimension(175, 500));
frame.add(flipButton, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(4, 4, 4, 4), 0, 0));
frame.add(textScroll, new GridBagConstraints(0, 1, 1, 3, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(4, 4, 4, 4), 0, 0));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
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();
}
} );
}
}
How I can cut a JTable into several parts of which each part has its own title, noting that all the data exists in the same database?
I want to do something like this.
Simple example to give you some ideas:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableSharedHeader extends JPanel
{
JComboBox comboBox;
TableSharedHeader()
{
JTable table1 = new JTable(5, 3);
JTable table2 = new JTable(5, 3);
table2.setTableHeader( table1.getTableHeader() );
table2.setColumnModel( table1.getColumnModel() );
JPanel tablePanel = new JPanel();
tablePanel.setLayout( new BoxLayout(tablePanel, BoxLayout.Y_AXIS) );
tablePanel.add( new JLabel("First table") );
tablePanel.add(table1);
tablePanel.add( new JLabel("Second table") );
tablePanel.add(table2);
setLayout( new BorderLayout() );
JScrollPane scrollPane = new JScrollPane( tablePanel );
scrollPane.setColumnHeaderView( table1.getTableHeader() );
add( scrollPane );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TableSharedHeader");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TableSharedHeader());
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();
}
});
*/
}
}
I want to append a value into a JTextField in Java. Something like:
String btn1="1";
textField.appendText(btn1);
I think you'll find setText is the answer. Just combine the current value with the new value:
textField.setText(textField.getText() + newStringHere);
If you text field is not editable, you could use:
textField.replaceSelection("...");
If it is editable you might use:
textField.setCaretPosition( textField.getDocument().getLength() );
textField.replaceSelection("...");
This would be slightly more efficient (than using setText()) because you are just appending text directly to the Document and would more resemble a JTextArea.append(...).
It would only result in a single DocumentEvent - insertUpdate().
You can also access the Document directly and do the insert:
Document doc = textField.getDocument();
doc.insertString(...);
but I find this more work because you also have to catch the BadLocationException.
Simple example, that also demonstrate the use of Key Bindings:
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.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(50, 50) );
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()
{
// UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
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();
}
});
}
}
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);