I am trying to create a window that shows a dynamic list of textFields and
if the number of textfields is large then I want to add a scroller.
I am using GridLayout.
The problem is that the panel I added the Jlist and scroller doesn't show anything, neither the list nor the scroller. Below you will find a part of my code.
//Label
JLabel numberOfTxt = new JLabel("Please enter the number in every TextField");
int n = 11; //A random number of TextFields
firstPanel.add(numberOfTxt, BorderLayout.NORTH); //Add label to panel
JList textFieldList = new JList(); //Create a list of TextFields
for (int i = 0; i < n; i++) {
//Add TextFields to list
JTextField textField = new JTextField();
textField.setBounds(0, 0, 6, 0);
textFieldList.add(textField);
System.out.println("textFieldList" + textFieldList);
}
textFieldList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
textFieldList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
textFieldList.setVisibleRowCount(8);
//Create scroller
JScrollPane listScroller = new JScrollPane(textFieldList);
listScroller.setBounds(0, 20, 600, 600);
//Create layout for panel where the textfields will be added
if (n % 2 != 0) {
n = n + 1;
}
thirdPanel.setLayout(new GridLayout(n / 2, 2, 10, 6));
thirdPanel.add(textFieldList);
thirdPanel.setVisible(true);
//ContentPane has BoxLayout
contentPane.add(firstPanel);
contentPane.add(thirdPanel);
contentPane.repaint();
window.pack();
}
window.revalidate();
}
});
JList does not works this way. If you really need a JList of TextFields you should use ListCellRenderer (probably you don't, see p.3).
You adding textFieldList both to listScroller and thirdPanel. Probably, you should replace thirdPanel.add(textFieldList); by thirdPanel.add(listScroller);.
thirdPanel uses GridLayout, but only one control is ever added to it. You should either add TextField directly to thirdPanel (easier way), or let the JList manage them.
Related
I'm creating a list of bank movements with the following code. pane is a JPanel and array is an ArrayList that contains respectively amount and description data. Setting is a little icon that allow you to modify each movement.
MouseClass is a class that extends MouseAdapter that I've created to add "k" index to mouseClicked method. I'm new with java gui programming. I'd like to know if there is a quick method to add a scroll to my panel
JLabel[] movement = new JLabel[array.size()];
JLabel[] description = new JLabel[array.size()];
JLabel[] data = new JLabel[array.size()];
JLabel[] setting = new JLabel[array.size()];
System.out.println(array.size());
int i = 0;
for(int k=0; k<array.size(); k++){
movement[k] = new JLabel("");
movement[k].setForeground(SystemColor.text);
movement[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
movement[k].setBounds(17, i, 145, 30);
movement[k].setText(array.get(array.size() - k - 1).getAmount() + "€");
panel.add(movement[k]);
description[k] = new JLabel("");
description[k].setForeground(SystemColor.text);
description[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
description[k].setBounds(187, i, 274, 30);
description[k].setText(array.get(array.size() - k - 1).getDescription());
panel.add(description[k]);
data[k] = new JLabel("");
data[k].setForeground(SystemColor.text);
data[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
data[k].setBounds(478, i, 145, 30);
data[k].setText(array.get(array.size() - k - 1).getDate());
panel.add(data[k]);
setting[k] = new JLabel();
setting[k].setIcon(new ImageIcon(List.class.getResource("/it/andreavaiuso/financemanager/images/edit.png")));
setting[k].setForeground(SystemColor.text);
setting[k].setFont(new Font("Segoe UI", Font.PLAIN, 20));
setting[k].addMouseListener(new MouseClass(array.size() - k - 1) {
#Override
public void mouseClicked(MouseEvent arg0) {
Modify mdf = new Modify(this.index);
mdf.setVisible(true);
dispose();
}
});
setting[k].setBounds(640, i, 82, 30);
panel.add(setting[k]);
i += 40;
}
But I don't know how to scroll it. I've tried woth JScrollPane but don't work!
I'm sure there is a simplest way to add these items to my panel...
I've tried woth JScrollPane but don't work!
Well I see lots of code with setBounds(...) which implies you are using a null layout.
Don't use a null layout. Swing was designed to be used with layout managers. In fact the scroll pane will only work when used with a layout manager because the scroll pane needs to know the preferred size of the panel so it can determine when you use scrollbars.
I would also suggest you should also be using a JTable for something like this. It is more efficient because you don't need to create individual components for each row of data. Read the section from the Swing tutorial on How to Use Tables for more information and examples.
For a JScrollPane you need, 1 JScrollPane, 1 JList and one DefaultListModel.
First you add your items to DefaultListModel, then you add the model to the JList and then you make a JSCrollPane with passing as argument your JList
Example:
DefaultListModel model = new DefaultListModel<String>();
JList list = new JList<String>();
model.addElemenet("1");
model.addElemenet("3");
model.addElemenet("2");
list.setModel(model);
JScrollPane scrollPane = new JScrollPane(list);
I have a dialog with several JTabbedPanes that can be minimized/maximized. However I have an issue when the tab is in minimized mode.
A small example of the code:
JDialog dialog = new JDialog();
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
JPanel tabPanel = new JPanel();
JTabbedPane tabPane = new JTabbedPane();
for (int i = 0; i < 5; i++) {
tabPane.addTab("Test" + i, new JPanel());
System.out.println(tabPane.getPreferredSize().height);
}
tabPanel.add(tabPane, BorderLayout.NORTH);
main.add(tabPanel, BorderLayout.CENTER);
dialog.add(main);
dialog.setPreferredSize(new Dimension(50, 100);
dialog.pack();
dialog.setVisible(true);
What I expected was a tab pane to be the smallest size possible, but I noticed that as I added more tabs, the height of the tabbed pane was increasing. This was the result from the print statement:
37, 55, 73, 91, 109
The fact that the height is increasing when tabs are added does not seem right to me since according to the documentation in https://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html, "The preferred size of the tabbed pane is just big enough to display its tallest child at its preferred height, and its widest child at its preferred width." I would expect that since I'm adding empty panels, the size would not change, but this does not seem to be the case. Is there anyway around this?
FYI, I am using the latest version of Java.
I have a window containing a JScrollArea, which contains a JPanel which contains a JTextArea. When I resize the window to make it larger, the layout updates perfectly, but if I make the window smaller, the JPanel does not shrink its contents. I attempted to add a ComponentListener on the JScrollArea to resize the JPanel based on the new size of the viewport, but this seems to defeat the purpose of the vertical scroll bar.
UPDATE: The idea here is that the JScrollArea will contain a JPanel (since it can only contain one component for its viewport), and within that JPanel I will be adding multiple JPanels containing components that describe processes that are running to the user. Since there could be any number of these processes running, I need to have some kind of scroll bar functionality available. Hence the component hierarchy I'm using below.
The desired behavior here is that the window can be resized larger or smaller and the text area will wrap its contents accordingly, and a vertical scroll bar will appear if the contents of the JPanel are larger vertically than the window. Any suggestions?
public class TestWindow extends JFrame {
JPanel scrollContentPanel;
JScrollPane scrollPane;
public TestWindow() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel();
this.setContentPane(mainPanel);
GridBagLayout mainPanelLayout = new GridBagLayout();
mainPanel.setLayout(mainPanelLayout);
scrollContentPanel = new JPanel();
scrollPane = new JScrollPane();
scrollPane.setViewportView(scrollContentPanel);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
GridBagLayout scrollContentLayout = new GridBagLayout();
scrollContentPanel.setLayout(scrollContentLayout);
JPanel contentEntry = new JPanel();
GridBagConstraints contentEntryConstraints = new GridBagConstraints();
contentEntryConstraints.weightx = 1.0;
contentEntryConstraints.insets = new Insets(3, 3, 5, 3);
contentEntryConstraints.fill = GridBagConstraints.BOTH;
contentEntryConstraints.gridx = 0;
contentEntryConstraints.gridy = 1;
scrollContentPanel.add(contentEntry, contentEntryConstraints);
GridBagLayout contentEntryLayout = new GridBagLayout();
contentEntry.setLayout(contentEntryLayout);
JTextArea descTextArea = new JTextArea();
descTextArea.setEditable(false);
descTextArea.setFont(new Font("Dialog", Font.PLAIN, 11));
descTextArea.setText("This is a description of an arbitrary unspecified length that may easily span multiple lines without any breaks in-between. Therefore it is necessary that the description automatically wrap as appropriate.");
descTextArea.setLineWrap(true);
descTextArea.setWrapStyleWord(true);
GridBagConstraints descTextAreaConstraints = new GridBagConstraints();
descTextAreaConstraints.weightx = 1.0;
descTextAreaConstraints.weighty = 1.0;
descTextAreaConstraints.insets = new Insets(0, 0, 3, 0);
descTextAreaConstraints.fill = GridBagConstraints.BOTH;
descTextAreaConstraints.gridx = 0;
descTextAreaConstraints.gridy = 1;
descTextAreaConstraints.gridwidth = 2;
contentEntry.add(descTextArea, descTextAreaConstraints);
GridBagConstraints scrollPaneConstraints = new GridBagConstraints();
scrollPaneConstraints.insets = new Insets(0, 0, 5, 0);
scrollPaneConstraints.weightx = 1.0;
scrollPaneConstraints.weighty = 1.0;
scrollPaneConstraints.fill = GridBagConstraints.BOTH;
scrollPaneConstraints.gridx = 0;
scrollPaneConstraints.gridy = 0;
mainPanel.add(scrollPane, scrollPaneConstraints);
scrollPane.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent evt) {
super.componentResized(evt);
scrollContentPanel.setPreferredSize(scrollPane.getViewportBorderBounds().getSize());
scrollContentPanel.validate();
}
});
pack();
}
public static void main(String[] args) {
TestWindow wnd = new TestWindow();
wnd.setVisible(true);
}
}
JTextArea should be placed directly into the JScrollPane, as long as that is the component your are trying to scroll. If there are other items you want to scroll with it (and hence the intermediate JPanel), then you might want to consider making that JPanel implement Scrollable so that the JScrollPane knows what to do with it. JTextArea implements Scrollable, which is why it works with JScrollPane out of the box.
no idea about your goal without detailed description, explanation
JTextArea should be placed in JScrollPane
set intial setPreferredSize for JTextArea, e.g. JTextArea(5, 10)
you are put three JPanels (is there reason ??? for this components hierarchy) one to JScrollPane, JTextArea is placed directly into JPanel instead of to the JScrollPane
then usage of ComponentListener is useless and contraproductive
I have been creating a system by which I am listing various seats on a train within a GUI. I had decided to use a simple grid layout with numbered JButtons representing the seats and the seatNo and empty JLabels to represent empty space (I realise this may be trivial but it was simple). I have used a Gridlayout and I have created the Buttons and Labels as shown below.
I have an List (compArray2) in a separate class that consists of 0s and 1s and a direction that represent where there should be a seat and where the shouldn't be a seat. the .getNum gets the value either 0 for empty space or 1 for a seat and the .getDir gets the direction the seat will be facing.
public JPanel rowPanelCreation(int type, int rowNo, int width){
theNoOfSeats=0;
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0,width));
List<seatLayout> layout = new ArrayList<>();
layout = ModelConstants.compArray2;
for (seatLayout isit : x2){
buttonEna = new JButton();
buttonEna.setFont(new Font("Sans Serif", Font.BOLD , 14));
buttonEna.setBorderPainted(false);
buttonDis = new JLabel();
if (isit.getNum()==0){
if (isit.getDir()=='x'){
panel.add(buttonDis);
}
}
else if (isit.getNum()==1){
theNoOfSeats++;
if (isit.getDir()=='N'){
image = new ImageIcon("/Users/Tomousee/NetBeansProjects/SortedList/src/Resources/chairDefaultN.png");
buttonEna.setIcon(image);
buttonEna.setText(String.valueOf(ModelConstants.compSeatNo.get(theNoOfSeats)));
buttonEna.setHorizontalTextPosition(JButton.CENTER);
buttonEna.setVerticalTextPosition(JButton.CENTER);
panel.add(buttonEna);
}
else if (isit.getDir()=='E'){
image = new ImageIcon("/Users/Tomousee/NetBeansProjects/SortedList/src/Resources/chairDefaultE.png");
buttonEna.setIcon(image);
buttonEna.setText(String.valueOf(ModelConstants.compSeatNo.get(theNoOfSeats)));
buttonEna.setHorizontalTextPosition(JButton.CENTER);
buttonEna.setVerticalTextPosition(JButton.CENTER);
buttonEna.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){JOptionPane.showMessageDialog(null,"You have chosen : ");}});
panel.add(buttonEna);
}
else if (isit.getDir()=='S'){
image = new ImageIcon("/Users/Tomousee/NetBeansProjects/SortedList/src/Resources/chairDefaultS.png");
buttonEna.setIcon(image);
buttonEna.setText(String.valueOf(ModelConstants.compSeatNo.get(theNoOfSeats)));
buttonEna.setHorizontalTextPosition(JButton.CENTER);
buttonEna.setVerticalTextPosition(JButton.CENTER);
panel.add(buttonEna);
}
else if (isit.getDir()=='W'){
image = new ImageIcon("/Users/Tomousee/NetBeansProjects/SortedList/src/Resources/chairDefaultW.png");
buttonEna.setIcon(image);
buttonEna.setText(String.valueOf(ModelConstants.compSeatNo.get(theNoOfSeats)));
buttonEna.setHorizontalTextPosition(JButton.CENTER);
buttonEna.setVerticalTextPosition(JButton.CENTER);
panel.add(buttonEna);
}
}
}
return panel;
}
the main problem I am having is that when I press one of the seat buttons I want a message to appear telling me the seatNo of the seat I have selected is. However when I do this it simply displays the very last seatNo. Is there a better way I could do this ? I'm assuming that as all the buttons are fundamentally the same, there is no way to differentiate between them ?
"I want a message to appear telling me the seatNo of the seat I have selected is. However when I do this it simply displays the very last seatNo."
Here's your problem. It's a reference problem. In the end, all the buttons will have the same JButton and JLabel reference. So all the buttons and labels will get the last button and label reference created, hence "displays the very last seatNo."
buttonEna = new JButton();
buttonEna.setFont(new Font("Sans Serif", Font.BOLD , 14));
buttonEna.setBorderPainted(false);
buttonDis = new JLabel();
You need to create a new JButton and new JLabel reference each iteration
JBUtton buttonEna = new JButton();
buttonEna.setFont(new Font("Sans Serif", Font.BOLD , 14));
buttonEna.setBorderPainted(false);
JLabel buttonDis = new JLabel();
Another approach would be to have an array of JButton, loop to set the buttons, and add them to the Panel. Say you have a GridLayout(2, 2). You then would need a array of 4 JButtons
JButton[] buttons = new JButton[9];
...
for (int i = 0; i < 4; i++){
buttons[i] = new JButton();
buttons[i].setFont(new Font("Sans Serif", Font.BOLD , 14));
buttonEna.setBorderPainted(false);
// set other properties for button
panel.add(buttons[i]);
}
How to place components in layout on specific position.
Like I want to place 2 text boxes in first row, below 3 combo boxes.
But when I am trying to put they all appear in one line and I have used flowlayout. I have used the border as well. When I am resizing, the window sizes of the components are going out from border.
Can you suggest me some layouts to use and how to use it?
Here is my code :
topPanel=new JPanel();
topPanel.setLayout(new FlowLayout());
topPanel.setBorder(new TitledBorder(new EtchedBorder(), "Customer Data"));
CNameTextField = new JTextField (20); // create the Customer Name text field
CNameTextField.setEditable(true); // set editable text box
CIDLabel=new JLabel("Customer ID");
C_IDTextField = new JTextField (10);
C_IDTextField.setEditable(true); // set editable text box
topPanel.add(CNameTextField);
topPanel.add(C_IDTextField);
// Create and populate Room type combo box
roomTypeCombo = new JComboBox();
roomTypeCombo.addItem( "Budget($50)" );
// Create and populate Meal type combo box
mealCombo = new JComboBox();
mealCombo.addItem( "None" );
// Create and populate Days combo box
daysCombo = new JComboBox();
for(int i=0;i<31 ; i++) {
// populate combobox with days
daysCombo.addItem(i);
}
// Adding rest of the components to top panel
topPanel.add(roomTypeCombo);
topPanel.add(mealCombo);
topPanel.add(daysCombo);
Thanks.
The most specific type of layout is absolute positioning.
Warning: Absolute positioning should rarely, if ever, be used. There are many reasons why. Here is one: Absolute positioning (No layout manager) vs. absolute positioning in MiGlayout
- Thanks to user brimborium for the good idea of adding a warning.
That being said, here is how to use absolute positioning:
In your code above, instead of setting topPanel's layout to FlowLayout, set it to null.
topPanel.setLayout(null);
Later on in the code, right before you start adding components to topPanel, call the container's setBounds method:
someJComponent.setBounds(x-coord, y-coord, width, height);
So for example you created an instance of JComboBox() and named it roomTypeCombo, the following code shows how to absolutely position roomTypeCombo.
topPanel.setLayout(null);
// code...
roomTypeCombo = new JComboBox();
// code...
roomTypeCombo.setBounds(100, 100, 200, 50);
topPanel.add(roomTypeCombo);
The setBounds method, used above, has four parameters:
int x-coord - set roomTypeCombo's x-coordinate relative to
its parent, topPanel.
int y-coord - set roomTypeCombo's y-coordinate relative to its parent, topPanel.
int width - specify roomTypeCombo's width.
int height - specify roomTypeCombo's height.
I would just play around with the coordinates and see if you like anything that comes out of it. The worst thing that could happen is that you go back to using a layout, which is probably better than absolute positioning. Or you could implement your own layout manager, if you follow this hyperlink the first answer talks about implementing your own layout manager and has helpful links.
More information on absolute positioning
Try to change the layout.
http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html
You could go for a GridLayout with two lines (for example, there is some others possible combinations), with each line containing respectively 3 JComboBoxs, and two JTextFields.
Look carefully at the documentation and check out some examples easily reachable on the web.
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class SwingResizeJFrame {
public SwingResizeJFrame() {
JTextField TextField1 = new JTextField("firstTextField");
JTextField TextField2 = new JTextField("secondTextField");
JPanel firstPanel = new JPanel();
firstPanel.setLayout(new GridLayout(0, 2, 10, 10));
firstPanel.add(TextField1);
firstPanel.add(TextField2);
JComboBox comboBox1 = new JComboBox(new Object[]{"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
JComboBox comboBox2 = new JComboBox(new Object[]{"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
JComboBox comboBox3 = new JComboBox(new Object[]{"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
JPanel secondPanel = new JPanel();
secondPanel.setLayout(new GridLayout(0, 3, 10, 10));
secondPanel.add(comboBox1);
secondPanel.add(comboBox2);
secondPanel.add(comboBox3);
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(2, 1, 10, 10));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(firstPanel);
frame.add(secondPanel);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
SwingResizeJFrame demo = new SwingResizeJFrame();
}
});
}
}