I am trying to make a Java JDialog where symbols are displayed in a tableish way. In fact something similar to charmap for windows:
But I ran into some issues:
I need the JDialog to be re-sizable so I can't choose to have a table as display, because it needs to be dynamically scaled.(To clarify I mean not just the adjustment of the width of every cell, but the actual amount of the cells in the row/column)
The symbols obviously need to be wrapped in some sort of listener friendly component. But if I choose JButtons, everything looks wrong, because of the different character width in pixel.
Since I have to loop through the symbols to create JButtons I can only make Objects with no name. So how do I even find out which button was pressed?
here is what I've got so far:
Code Updated 05.12.2014
import java.awt.Dimension;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class SymbolDialog extends JDialog{
private char[] math = {8704, 8707, 8708, 8710, 8712, 8713, 8715, 8716, 8721, 8723, 8728, 8730, 8734, 8743, 8744, 8745, 8746, 8747, 8776, 8793, 8800, 8801, 8804, 8805, 8834, 8835, 8836, 8837, 8838, 8839};
private final String[] sTypes = {"Math","Logic", "Arrows"};
private JPanel pan = new JPanel();
public SymbolDialog(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
System.out.println("catdch 1");
} catch (InstantiationException e1) {
System.out.println("catdch 2");
} catch (IllegalAccessException e1) {
System.out.println("catdch 3");
} catch (UnsupportedLookAndFeelException e1) {
System.out.println("catdch 4");
}
SwingUtilities.updateComponentTreeUI(this);
pan.setPreferredSize(new Dimension(428, 70));
pan.setLayout(new ColumnsFlowLayout(0,0));
// Button Build
for (int i = 0; i < math.length; i++){
pan.add(new JButton(math[i]+""));
}
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0};
gridBagLayout.rowHeights = new int[]{0, 0, 0};
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
getContentPane().setLayout(gridBagLayout);
JPanel panel = new JPanel();
panel.setBorder(new EmptyBorder(5,10,0,10));
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.anchor = GridBagConstraints.WEST;
gbc_panel.fill = GridBagConstraints.VERTICAL;
gbc_panel.insets = new Insets(0, 0, 5, 0);
gbc_panel.gridx = 0;
gbc_panel.gridy = 0;
getContentPane().add(panel, gbc_panel);
GridBagLayout gbl_panel = new GridBagLayout();
gbl_panel.columnWidths = new int[]{0, 0, 0};
gbl_panel.rowHeights = new int[]{0, 0};
gbl_panel.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
gbl_panel.rowWeights = new double[]{0.0, Double.MIN_VALUE};
panel.setLayout(gbl_panel);
JLabel lblCathegorie = new JLabel("Categories:");
GridBagConstraints gbc_lblCathegorie = new GridBagConstraints();
gbc_lblCathegorie.insets = new Insets(0, 0, 0, 5);
gbc_lblCathegorie.gridx = 0;
gbc_lblCathegorie.gridy = 0;
panel.add(lblCathegorie, gbc_lblCathegorie);
JComboBox<Object> comboBox = new JComboBox<Object>(sTypes);
GridBagConstraints gbc_comboBox = new GridBagConstraints();
gbc_comboBox.gridx = 1;
gbc_comboBox.gridy = 0;
panel.add(comboBox, gbc_comboBox);
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.gridx = 0;
gbc_scrollPane.gridy = 1;
getContentPane().add(pan, gbc_scrollPane);
// Pack
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setResizable(true);
pack();
setTitle("Symbols");
setVisible(true);
}
public void actionPerformed(ActionEvent event) {
//TODO sysout which symbol was clicked
System.out.println(((JButton) event.getSource()).getText());
}
public static void main(String[] args){
new SymbolDialog();
}
}
ps: I use the recommended columns_flow_layout from here
I would use JButton[][] in a GridLayout.
For adding them to the JPanel you could use for in a for loop like so:
for(int row = 0; row < ITEMS-PER-ROW; row++){
for(int col = 0; col < ITEMS-PER-COL; col++){
JButton[row][col] = new JButton(/*SignToShowAs String[][]*/)
}
}
Related
I am doing a computer studies controlled assessment. This is an encryption/decryption program. However, I am trying to listen to a button in one class called Gui_Maker, which makes the GUI and all the swing elements. I then want to pass the information to a method in another class called Computerscience. However every time I press the button I get an error.
I am not advanced at all in Java, and it would help if any explanation gave any code I should put into my program, and explained in laymen's terms.
Here's my code:
package computerscience;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JTextArea;
public class Gui_Maker implements ActionListener {
Computerscience computerscience = new Computerscience();
JButton btnEncrypt = new JButton("Encrypt");
JButton btnDecrypt = new JButton("Decrypt");
JButton btnOpen = new JButton("Open");
protected JLabel lblEnterYourMessage;
protected JLabel lblEnterYourOffset;
protected JTextArea txtrMessage;
protected JTextArea txtrOffset;
private JFrame frame;
boolean test;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Gui_Maker window = new Gui_Maker();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Gui_Maker() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
btnEncrypt.addActionListener(this);
btnDecrypt.addActionListener(this);
btnOpen.addActionListener(this);
frame = new JFrame();
frame.setBounds(100, 100, 475, 240);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] { 0, 0, 0 };
gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0 };
gridBagLayout.columnWeights = new double[] { 1.0, 0.0, Double.MIN_VALUE };
gridBagLayout.rowWeights = new double[] { 1.0, 1.0, 1.0, 1.0 };
frame.getContentPane().setLayout(gridBagLayout);
JLabel lblEnterYourMessage = new JLabel("Enter your message here");
GridBagConstraints gbc_lblEnterYourMessage = new GridBagConstraints();
gbc_lblEnterYourMessage.anchor = GridBagConstraints.SOUTH;
gbc_lblEnterYourMessage.insets = new Insets(0, 0, 5, 5);
gbc_lblEnterYourMessage.gridx = 0;
gbc_lblEnterYourMessage.gridy = 0;
frame.getContentPane()
.add(lblEnterYourMessage, gbc_lblEnterYourMessage);
JTextArea txtrMessage = new JTextArea();
txtrMessage.setText("Message");
GridBagConstraints gbc_txtrMessage = new GridBagConstraints();
gbc_txtrMessage.insets = new Insets(0, 0, 5, 5);
gbc_txtrMessage.fill = GridBagConstraints.BOTH;
gbc_txtrMessage.gridx = 0;
gbc_txtrMessage.gridy = 1;
frame.getContentPane().add(txtrMessage, gbc_txtrMessage);
GridBagConstraints gbc_btnEncrypt = new GridBagConstraints();
gbc_btnEncrypt.fill = GridBagConstraints.VERTICAL;
gbc_btnEncrypt.insets = new Insets(0, 0, 5, 0);
gbc_btnEncrypt.gridx = 1;
gbc_btnEncrypt.gridy = 1;
frame.getContentPane().add(btnEncrypt, gbc_btnEncrypt);
JLabel lblEnterYourOffset = new JLabel("Enter your offset here");
GridBagConstraints gbc_lblEnterYourOffset = new GridBagConstraints();
gbc_lblEnterYourOffset.anchor = GridBagConstraints.SOUTH;
gbc_lblEnterYourOffset.insets = new Insets(0, 0, 5, 5);
gbc_lblEnterYourOffset.gridx = 0;
gbc_lblEnterYourOffset.gridy = 2;
frame.getContentPane().add(lblEnterYourOffset, gbc_lblEnterYourOffset);
GridBagConstraints gbc_btnDecrypt = new GridBagConstraints();
gbc_btnDecrypt.fill = GridBagConstraints.VERTICAL;
gbc_btnDecrypt.insets = new Insets(0, 0, 5, 0);
gbc_btnDecrypt.gridx = 1;
gbc_btnDecrypt.gridy = 2;
frame.getContentPane().add(btnDecrypt, gbc_btnDecrypt);
JTextArea txtrOffset = new JTextArea();
txtrOffset.setText("Offset");
GridBagConstraints gbc_txtrOffset = new GridBagConstraints();
gbc_txtrOffset.insets = new Insets(0, 0, 0, 5);
gbc_txtrOffset.fill = GridBagConstraints.BOTH;
gbc_txtrOffset.gridx = 0;
gbc_txtrOffset.gridy = 3;
frame.getContentPane().add(txtrOffset, gbc_txtrOffset);
GridBagConstraints gbc_btnOpen = new GridBagConstraints();
gbc_btnOpen.fill = GridBagConstraints.VERTICAL;
gbc_btnOpen.gridx = 1;
gbc_btnOpen.gridy = 3;
frame.getContentPane().add(btnOpen, gbc_btnOpen);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnEncrypt) {
String input_text;
int input_offset;
test = true;
input_text = txtrMessage.getText();
input_offset = Integer.parseInt(txtrOffset.getText());
computerscience.encrypt(input_text, input_offset, test);
}
if (e.getSource() == btnDecrypt) {
String input_text;
int input_offset;
test = false;
input_text = txtrMessage.getText();
input_offset = Integer.parseInt(txtrOffset.getText());
computerscience.decrypt(input_text, input_offset, test);
}
if (e.getSource() == btnOpen) {
}
}
}
These are fields in your class:
protected JTextArea txtrMessage;
protected JTextArea txtrOffset;
Here you recreate objects locally in a method
JTextArea txtrMessage = new JTextArea();
//...
JTextArea txtrOffset = new JTextArea();
And in another method you access the uninitialized fields:
input_text = txtrMessage.getText();
input_offset = Integer.parseInt(txtrOffset.getText());
Omit the types from the code in the init method.
txtrMessage = new JTextArea();
//...
txtrOffset = new JTextArea();
And so for some other JComponents, although it doesn't hurt with these:
lblEnterYourMessage = ...
lblEnterYourOffset = ...
So using WindowBuilder (latest version of Ecliple, Kepler) I've created a frame as so:
But I'd like to switch between them with a button, which I've created on the panelWelcome.
I'm guessing I'd add an itemListener, then create a method that switches between the cards.
The problem is, I have no idea how to proceed after that. Here's the code that's automatically generated:
package client;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.CardLayout;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class Test {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Test window = new Test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Test() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new CardLayout(0, 0));
JPanel panelWelcome = new JPanel();
frame.getContentPane().add(panelWelcome, "name_98933171901972");
GridBagLayout gbl_panelWelcome = new GridBagLayout();
gbl_panelWelcome.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0};
gbl_panelWelcome.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
gbl_panelWelcome.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
gbl_panelWelcome.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
panelWelcome.setLayout(gbl_panelWelcome);
JLabel lblTitle = new JLabel("MEMEPlayer");
lblTitle.setFont(new Font("Segoe UI", Font.BOLD, 12));
GridBagConstraints gbc_lblTitle = new GridBagConstraints();
gbc_lblTitle.insets = new Insets(0, 0, 5, 0);
gbc_lblTitle.gridx = 5;
gbc_lblTitle.gridy = 0;
panelWelcome.add(lblTitle, gbc_lblTitle);
JLabel lblNewLabel = new JLabel("Welcome! To get started, select a movie from the drop down menu");
lblNewLabel.setFont(new Font("Segoe UI", Font.PLAIN, 11));
GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
gbc_lblNewLabel.insets = new Insets(0, 0, 5, 0);
gbc_lblNewLabel.gridx = 5;
gbc_lblNewLabel.gridy = 2;
panelWelcome.add(lblNewLabel, gbc_lblNewLabel);
JComboBox comboBox = new JComboBox();
comboBox.setModel(new DefaultComboBoxModel(new String[] {"The Avengers (2012)", "Monsters, Inc. (2001)", "Prometheus (2012)"}));
GridBagConstraints gbc_comboBox = new GridBagConstraints();
gbc_comboBox.insets = new Insets(0, 0, 5, 0);
gbc_comboBox.gridx = 5;
gbc_comboBox.gridy = 4;
panelWelcome.add(comboBox, gbc_comboBox);
JButton btnNewButton = new JButton("Next >");
GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
gbc_btnNewButton.insets = new Insets(0, 0, 5, 0);
gbc_btnNewButton.gridx = 5;
gbc_btnNewButton.gridy = 6;
btnNewButton.addItemListener((ItemListener) this);
panelWelcome.add(btnNewButton, gbc_btnNewButton);
JLabel lblNewLabel_1 = new JLabel("");
lblNewLabel_1.setIcon(new ImageIcon("C:\\temp\\Meme1\\largeVLC.png"));
GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
gbc_lblNewLabel_1.gridx = 5;
gbc_lblNewLabel_1.gridy = 8;
panelWelcome.add(lblNewLabel_1, gbc_lblNewLabel_1);
JPanel panelVideo = new JPanel();
frame.getContentPane().add(panelVideo, "name_98968999152440");
}
}
Thanks for any help!
The problem I see you're facing is that you are setting the layout to the frame. This is a problem because it means that the frame can only have on visible component at a time. That component being one of the panels. So you can put a button. The button would have to be on the one of the panels, which may be hard to maintain, in terms of navigation.
So instead, have a main JPanel that has the CardLayout, and add your card panels to that main panel. Then you can add the main panel to the frame, along with buttons for navigation.
Another option is to have a menu bar with option to change the cards, then that way, you can keep the card layout on the frame, because navigation is controlled by the menu options.
See How to Use CardLayout if you're not really sure even how to use CardLayout, hand coding. You're going to need a reference to layout and call one of its navigation methods like show(), next(), or previous()
You may also find this post interesting. It used Netbeans, but maybe you'll pick something up
Im new to GUI's in Java and having a hell of a time understanding this:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.GridBagLayout;
public class Main extends JFrame {
private JPanel contentPane;
static JPanel panel;
static JScrollPane scrollPane;
static JButton btnStart;
private static String compTestArray[];
static Integer indexer = 0;
static List<JLabel> listOfLabels = new ArrayList<JLabel>();
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 739, 456);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
btnStart = new JButton("Start");
btnStart.setBounds(10, 379, 89, 23);
btnStart.addActionListener(new ButtonListener());
contentPane.add(btnStart);
panel = new JPanel();
panel.setBounds(10, 11, 513, 359);
contentPane.add(panel);
scrollPane = new JScrollPane(panel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
GridBagLayout gbl_panel = new GridBagLayout();
gbl_panel.columnWidths = new int[] { 0, 0, 0 };
gbl_panel.rowHeights = new int[] { 0, 0, 0, 0 };
gbl_panel.columnWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
gbl_panel.rowWeights = new double[] { 0.0, 0.0, 0.0, Double.MIN_VALUE };
panel.setLayout(gbl_panel);
scrollPane.setBounds(10, 11, 633, 359);
contentPane.add(scrollPane);
compTestArray = new String[2];
compTestArray[0] = "172.16.98.3";
compTestArray[1] = "172.16.98.6";
}
static class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
//String labelText = "Computer Name\tTest Name\tIteration\tPass\tFail\tCrashes\tStart\tStop";
//labelText = labelText.replaceAll("\t", " ");
listOfLabels.add(new JLabel("Computer"));
for(int ix = 0; ix < compTestArray.length; ix++){
// Clear panel
panel.removeAll();
//labelText = compTestArray[indexer] + "\tKPI_1_1_1_1\t" + ix + "/20\t1\t\t0\t\t0\t\t12:00\t12:30";
//labelText = labelText.replaceAll("\t", " ");
listOfLabels.add(new JLabel(compTestArray[indexer]));
System.out.println("indexer is " + indexer);
// Create constraints
GridBagConstraints labelConstraints = new GridBagConstraints();
// Add labels and text fields
for (int i = 0; i < indexer+2; i++) {
// Label constraints
labelConstraints.gridx = 0;
labelConstraints.gridy = i;
labelConstraints.weightx = 0;
labelConstraints.insets = new Insets(10, 10, 10, 10);
// Add them to panel
panel.add(listOfLabels.get(i), labelConstraints);
}
// Align components top-to-bottom
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = indexer;
c.weighty = 1;
panel.add(new JLabel(), c);
// Increment indexer
indexer++;
// Repaint the GUI
scrollPane.validate();
} // Close for loop
// Disable Start button
btnStart.setEnabled(false);
} // Close public void actionPerformed(ActionEvent arg0)
} // Close static class ButtonListener implements ActionListener
}
Output:
I have this issue with my program that I can't seem to figure out why its happening. What should happen is that when you enter in something in the input area below, it should take that and put it where the black line is which is actually a textarea box. Normally it works except that when I have both editable set to false and line wrap set the true this happens and the size should stretch across the whole panel up to the image. I've put down below the relevant code. I have been racked my brain for hours and need a new perspective.
private JTextArea message = new JTextArea(5,20);
private JLabel date = new JLabel();
private ImageIcon img = new ImageIcon(getClass().getResource("/assignment1/img/silhouette.png"));
private JLabel ImageLabel = new JLabel();
public MessagePanel(String pmessage, Date timestamp) {
this.setLayout(new GridBagLayout());
this.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
this.setPreferredSize(new Dimension(550,150));
ImageLabel.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
message.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
ImageLabel.setIcon(img);
message.setEditable(false);
message.append(pmessage);
message.setLineWrap(true);
message.setWrapStyleWord(true);
message.setCaretPosition(message.getDocument().getLength());
//message.setText(pmessage);
message.setPreferredSize(new Dimension(400,100));
SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
date.setText(f.format(timestamp));
GridBagConstraints messageConst = new GridBagConstraints();
messageConst.gridx = 0;
messageConst.gridy = 0;
messageConst.fill = GridBagConstraints.HORIZONTAL;
//messageConst.anchor = java.awt.GridBagConstraints.NORTHWEST;
messageConst.insets = new Insets(12, 83, 0, 0);
GridBagConstraints iconConst = new GridBagConstraints();
iconConst.gridx = 1;
iconConst.gridy = 0;
iconConst.anchor = java.awt.GridBagConstraints.NORTHWEST;
iconConst.insets = new Insets(49, 425, 0, 11);
GridBagConstraints dateConst = new GridBagConstraints();
dateConst.gridx = 0;
dateConst.gridy = 1;
dateConst.gridwidth = 2;
dateConst.ipadx = 70;
dateConst.anchor = GridBagConstraints.NORTHWEST;
dateConst.insets = new Insets(6, 460,0, 11);
this.add(message,messageConst);
this.add(date,dateConst);
this.add(ImageLabel,iconConst);
}
Instead of using dateConst.ipadx = 70; which may effecting GridBagLayout's ability to honor the preferred size of the text area, try using messageConst.weightx = 1; instead.
The issue could that GridBagLayout has looked at the available space for the text area and decided there isn't enough space to honor it's preferred size and resorts to using it's minimum size instead (which is typically not very large)
Updated
So I had a quick play around with the code and came up with this...
Things to remember, insest add weight to a given cell, making it bigger, which will push other cells around, not always in a good way.
EAST is to the right, WEST is to the left ;)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class TestTextArea100 {
public static void main(String[] args) {
new TestTextArea100();
}
public TestTextArea100() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea message = new JTextArea(5, 20);
private JLabel date = new JLabel();
private JLabel ImageLabel = new JLabel();
public TestPane() {
this.setLayout(new GridBagLayout());
this.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
this.setPreferredSize(new Dimension(550, 150));
ImageLabel.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
message.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
ImageLabel.setText(":)");
ImageLabel.setBorder(new LineBorder(Color.RED));
message.setEditable(false);
message.append("Blah");
message.setLineWrap(true);
message.setWrapStyleWord(true);
message.setCaretPosition(message.getDocument().getLength());
//message.setText(pmessage);
message.setPreferredSize(new Dimension(400, 100));
SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
date.setText(f.format(new Date()));
GridBagConstraints messageConst = new GridBagConstraints();
messageConst.gridx = 0;
messageConst.gridy = 0;
messageConst.weightx = 1;
messageConst.weighty = 1;
messageConst.fill = GridBagConstraints.BOTH;
messageConst.insets = new Insets(12, 12, 12, 12);
GridBagConstraints iconConst = new GridBagConstraints();
iconConst.gridx = 1;
iconConst.gridy = 0;
iconConst.insets = new Insets(12, 12, 12, 12);
GridBagConstraints dateConst = new GridBagConstraints();
dateConst.gridx = 0;
dateConst.gridy = 1;
dateConst.gridwidth = 2;
dateConst.anchor = GridBagConstraints.EAST;
this.add(message, messageConst);
this.add(date, dateConst);
this.add(ImageLabel, iconConst);
}
}
}
MAIN PROBLEM: In a JScrollPane with JPanel which contains a JTextArea, text wraps up if GUI is expanded but text does not wrap back when GUI is contracted. See example below
Okay I am building the GUI for an app I am currently working on and I am having a bit of a problem.
The explanation: My GUI is structured as illustrated below:
And this is what it looks like.
Upon expansion the the JTextArea inside the panelWithText expands and resizes the text as such:
But the problem is what happens when you make the GUI smaller. The "problem" is that I want the text to warp back as it was before. I did a little experimenting by implementing a ComponentListener to both the JScrollPane and the panelWithText and found out that componentResized is being called for panelWithText upon expansion but not for contraction. Is there any way to implement the behavior of the text warping back in the panelWithText Component?
PS: Apparently if I switch the JScrollPane with a regular JPanel it works. But I can't do that! I have a LOT of panelWithText to show to the user.
PS PS: Sorry here is the code I am using.
JFrameExt.java
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JScrollPane;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.FlowLayout;
import java.awt.Window.Type;
import javax.swing.ScrollPaneConstants;
import java.awt.CardLayout;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.factories.FormFactory;
public class JFrameExt extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JFrameExt frame = new JFrameExt();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public JFrameExt() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 246, 164);
contentPane = new JPanel();
contentPane.setBorder(null);
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportBorder(null);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
contentPane.add(scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
scrollPane.setViewportView(panel);
GridBagLayout gbl_panel = new GridBagLayout();
gbl_panel.columnWidths = new int[]{0, 0};
gbl_panel.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gbl_panel.rowWeights = new double[]{0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
panel.setLayout(gbl_panel);
panelWithText panelWithText_ = new panelWithText();
GridBagConstraints gbc_panelWithText_ = new GridBagConstraints();
gbc_panelWithText_.anchor = GridBagConstraints.NORTH;
gbc_panelWithText_.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText_.fill = GridBagConstraints.HORIZONTAL;
gbc_panelWithText_.gridx = 0;
gbc_panelWithText_.gridy = 0;
panel.add(panelWithText_, gbc_panelWithText_);
panelWithText panelWithText__1 = new panelWithText();
GridBagConstraints gbc_panelWithText__1 = new GridBagConstraints();
gbc_panelWithText__1.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText__1.anchor = GridBagConstraints.NORTH;
gbc_panelWithText__1.fill = GridBagConstraints.HORIZONTAL;
gbc_panelWithText__1.gridx = 0;
gbc_panelWithText__1.gridy = 1;
panel.add(panelWithText__1, gbc_panelWithText__1);
panelWithText panelWithText__2 = new panelWithText();
GridBagConstraints gbc_panelWithText__2 = new GridBagConstraints();
gbc_panelWithText__2.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText__2.fill = GridBagConstraints.BOTH;
gbc_panelWithText__2.gridx = 0;
gbc_panelWithText__2.gridy = 2;
panel.add(panelWithText__2, gbc_panelWithText__2);
panelWithText panelWithText__3 = new panelWithText();
GridBagConstraints gbc_panelWithText__3 = new GridBagConstraints();
gbc_panelWithText__3.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText__3.fill = GridBagConstraints.BOTH;
gbc_panelWithText__3.gridx = 0;
gbc_panelWithText__3.gridy = 3;
panel.add(panelWithText__3, gbc_panelWithText__3);
panelWithText panelWithText__4 = new panelWithText();
GridBagConstraints gbc_panelWithText__4 = new GridBagConstraints();
gbc_panelWithText__4.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText__4.fill = GridBagConstraints.BOTH;
gbc_panelWithText__4.gridx = 0;
gbc_panelWithText__4.gridy = 4;
panel.add(panelWithText__4, gbc_panelWithText__4);
panelWithText panelWithText__5 = new panelWithText();
GridBagConstraints gbc_panelWithText__5 = new GridBagConstraints();
gbc_panelWithText__5.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText__5.fill = GridBagConstraints.BOTH;
gbc_panelWithText__5.gridx = 0;
gbc_panelWithText__5.gridy = 5;
panel.add(panelWithText__5, gbc_panelWithText__5);
panelWithText panelWithText__6 = new panelWithText();
GridBagConstraints gbc_panelWithText__6 = new GridBagConstraints();
gbc_panelWithText__6.fill = GridBagConstraints.BOTH;
gbc_panelWithText__6.gridx = 0;
gbc_panelWithText__6.gridy = 6;
panel.add(panelWithText__6, gbc_panelWithText__6);
setSize(300,100);
}
}
panelWithText.java
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JTextArea;
import javax.swing.ImageIcon;
import java.awt.BorderLayout;
public class panelWithText extends JPanel {
/**
* Create the panel.
*/
public void me_resized(Dimension d){
System.out.println("CALLED..");
super.setPreferredSize(d);
}
public panelWithText() {
setBackground(Color.DARK_GRAY);
setForeground(Color.WHITE);
setLayout(new BorderLayout(0, 0));
JTextArea txtrIveBeenReading = new JTextArea();
txtrIveBeenReading.setEditable(false);
txtrIveBeenReading.setColumns(28);
txtrIveBeenReading.setFont(new Font("Tahoma", Font.PLAIN, 10));
txtrIveBeenReading.setLineWrap(true);
txtrIveBeenReading.setWrapStyleWord(true);
txtrIveBeenReading.setText("\n A bunch of really important text here... A bunch of really important text here... A bunch of really important text here... A bunch of really important text here...\n");
txtrIveBeenReading.setForeground(Color.WHITE);
txtrIveBeenReading.setBackground(Color.DARK_GRAY);
add(txtrIveBeenReading, BorderLayout.CENTER);
}
}
After a little playing around, I came up with this...
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JFrameExt frame = new JFrameExt();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public static class ScrollablePane extends JPanel implements Scrollable {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(100, 100);
}
#Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
#Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
#Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
#Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
public static class JFrameExt extends JFrame {
private JPanel contentPane;
/**
* Create the frame.
*/
public JFrameExt() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 246, 164);
contentPane = new JPanel();
contentPane.setBorder(null);
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportBorder(null);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
contentPane.add(scrollPane, BorderLayout.CENTER);
JPanel panel = new ScrollablePane();
scrollPane.setViewportView(panel);
GridBagLayout gbl_panel = new GridBagLayout();
// gbl_panel.columnWidths = new int[]{0, 0};
// gbl_panel.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
// gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE};
// gbl_panel.rowWeights = new double[]{0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
panel.setLayout(gbl_panel);
panelWithText panelWithText_ = new panelWithText();
GridBagConstraints gbc_panelWithText_ = new GridBagConstraints();
gbc_panelWithText_.anchor = GridBagConstraints.NORTH;
gbc_panelWithText_.insets = new Insets(0, 0, 5, 0);
gbc_panelWithText_.fill = GridBagConstraints.HORIZONTAL;
gbc_panelWithText_.gridx = 0;
gbc_panelWithText_.gridy = 0;
gbc_panelWithText_.weightx = 1;
panel.add(panelWithText_, gbc_panelWithText_);
// panelWithText panelWithText__1 = new panelWithText();
// GridBagConstraints gbc_panelWithText__1 = new GridBagConstraints();
// gbc_panelWithText__1.insets = new Insets(0, 0, 5, 0);
// gbc_panelWithText__1.anchor = GridBagConstraints.NORTH;
//// gbc_panelWithText__1.fill = GridBagConstraints.HORIZONTAL;
// gbc_panelWithText__1.gridx = 0;
// gbc_panelWithText__1.gridy = 1;
// panel.add(panelWithText__1, gbc_panelWithText__1);
//
// panelWithText panelWithText__2 = new panelWithText();
// GridBagConstraints gbc_panelWithText__2 = new GridBagConstraints();
// gbc_panelWithText__2.insets = new Insets(0, 0, 5, 0);
//// gbc_panelWithText__2.fill = GridBagConstraints.BOTH;
// gbc_panelWithText__2.gridx = 0;
// gbc_panelWithText__2.gridy = 2;
// panel.add(panelWithText__2, gbc_panelWithText__2);
//
// panelWithText panelWithText__3 = new panelWithText();
// GridBagConstraints gbc_panelWithText__3 = new GridBagConstraints();
// gbc_panelWithText__3.insets = new Insets(0, 0, 5, 0);
//// gbc_panelWithText__3.fill = GridBagConstraints.BOTH;
// gbc_panelWithText__3.gridx = 0;
// gbc_panelWithText__3.gridy = 3;
// panel.add(panelWithText__3, gbc_panelWithText__3);
//
// panelWithText panelWithText__4 = new panelWithText();
// GridBagConstraints gbc_panelWithText__4 = new GridBagConstraints();
// gbc_panelWithText__4.insets = new Insets(0, 0, 5, 0);
//// gbc_panelWithText__4.fill = GridBagConstraints.BOTH;
// gbc_panelWithText__4.gridx = 0;
// gbc_panelWithText__4.gridy = 4;
// panel.add(panelWithText__4, gbc_panelWithText__4);
//
// panelWithText panelWithText__5 = new panelWithText();
// GridBagConstraints gbc_panelWithText__5 = new GridBagConstraints();
// gbc_panelWithText__5.insets = new Insets(0, 0, 5, 0);
//// gbc_panelWithText__5.fill = GridBagConstraints.BOTH;
// gbc_panelWithText__5.gridx = 0;
// gbc_panelWithText__5.gridy = 5;
// panel.add(panelWithText__5, gbc_panelWithText__5);
//
// panelWithText panelWithText__6 = new panelWithText();
// GridBagConstraints gbc_panelWithText__6 = new GridBagConstraints();
//// gbc_panelWithText__6.fill = GridBagConstraints.BOTH;
// gbc_panelWithText__6.gridx = 0;
// gbc_panelWithText__6.gridy = 6;
// panel.add(panelWithText__6, gbc_panelWithText__6);
setSize(300, 100);
}
}
public static class panelWithText extends JPanel {
/**
* Create the panel.
*/
public void me_resized(Dimension d) {
System.out.println("CALLED..");
super.setPreferredSize(d);
}
public panelWithText() {
setBackground(Color.DARK_GRAY);
setForeground(Color.WHITE);
setLayout(new BorderLayout(0, 0));
JTextArea txtrIveBeenReading = new JTextArea();
txtrIveBeenReading.setEditable(false);
txtrIveBeenReading.setColumns(28);
txtrIveBeenReading.setFont(new Font("Tahoma", Font.PLAIN, 10));
txtrIveBeenReading.setLineWrap(true);
txtrIveBeenReading.setWrapStyleWord(true);
txtrIveBeenReading.setText("\n A bunch of really important text here... A bunch of really important text here... A bunch of really important text here... A bunch of really important text here...\n");
txtrIveBeenReading.setForeground(Color.WHITE);
txtrIveBeenReading.setBackground(Color.DARK_GRAY);
add(txtrIveBeenReading, BorderLayout.CENTER);
}
}
}
Basically, you need a container that implements the Scrollable interface. This will allow you to specify that the container should track/match the view ports width. This will cause the container to be laid out when ever the view port changes size...
As a side note, you can use a single copy of the GridBagConstraints, when you add each new component to the container, the GridBagLayout will generate a copy of it's own. This is very powerful when you want to share properties of the GridBagConstraints between components ;)