Create a list of entries and make each entry clickable - java

I am trying to create an UI which has two panes.
In the left pane I display the list of files and right pane displays the contents.
Now, I want list of files in the left pane to look as a normal list. But when I click an entry in this list, the contents of the particular file should be displayed in the right pane.
How can I achieve this using Swing?

Here I have done a short example, with the help of JList on the left and JTextArea on right. I have used ListSelectionListener to get the item list change. Use a LayoutManager as per your convenience.
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class JListTest {
private JList jList1;
private JPanel jPanel1;
private JTextArea jTextArea1;
public JListTest() {
initComponents();
}
private void initComponents() {
JFrame f = new JFrame();
jPanel1 = new JPanel();
jList1 = new JList();
jTextArea1 = new JTextArea();
jList1.setModel(new AbstractListModel() {
String[] strings = {"Item 1", "Item 2"};
#Override
public int getSize() {
return strings.length;
}
#Override
public Object getElementAt(int i) {
return strings[i];
}
});
jList1.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent evt) {
jList1ValueChanged(evt);
}
});
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jPanel1.add(jList1);
jPanel1.add(jTextArea1);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.add(jPanel1);
f.pack();
f.setVisible(true);
}
private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {
//set text on right here
String s = (String) jList1.getSelectedValue();
if (s.equals("Item 1")) {
jTextArea1.setText("You clicked on list 1");
}
if (s.equals("Item 2")) {
jTextArea1.setText("You clicked on list 2");
}
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JListTest();
}
});
}
}

Check out this tutorial. It explains how to use lists in Swing, including event handlers that are necessary to register for click events.

You might want to look at this JTree example.

first off, you have not even tried yet, right? Swing does almost everything input related with listeneres. Check out the mouse listener, or adjust the awnser giving below
https://stackoverflow.com/a/4344762/258418
For completness I quote it here:
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
list.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
JList list = (JList)evt.getSource();
if (evt.getClickCount() == 2) {
int index = list.locationToIndex(evt.getPoint());
} else if (evt.getClickCount() == 3) { // Triple-click
int index = list.locationToIndex(evt.getPoint());
}
}
});
I am sure you can make it take single clicks as well,... if not write a comment

Some examples for reference:
FileBrowser uses a JTree on the left and nested detail panels on the right.
ImageDisplay embeds a custom JFileChooser on the left and displays a scrollable image on the right.
CheckTable shows a JTable on the left and a DisplayPanel on the right.

Use JList.addListSelectionListener(ListSelectionListener).
See How to Write a List Selection Listener for more examples.

Related

JButton in array wont update text

I've created an array of buttons, added them to my frame and (inefficiently) created action listeners for each of them which open a JOptionPane to take an input and add it to a String array, yet the text on the array button does not update after the popup is closed, while a button not part of an array updates its text fine.
The string array grabs the data from the JOptionPane fine, it just wont update the button's caption.
In my full program I'm writing ar_str_vals to a .xml file, and it can properly save and load the array, and surprisingly the array buttons properly set their text but only at the beginning of my program.
package wtf;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Wtf extends JFrame{
JButton[] ar_btn_vals = new JButton[2];
String[] ar_str_vals = new String[2];
public Wtf(){
super("Title");
setLayout(null);
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
constructor();
actionlisteners();
}
public void constructor(){
for (int x = 0;x<=1;x++){
ar_btn_vals[x] = new JButton();
ar_btn_vals[x].setText(ar_str_vals[x]);
ar_btn_vals[x].setBounds(5,(100 * x)+20, 100,40);
ar_btn_vals[x].setVisible(true);
add(ar_btn_vals[x]);
System.out.println(ar_str_vals[x]);
}
}
public void actionlisteners(){
for (int x=0;x<=1;x++){
switch (x){
case 0:
ar_btn_vals[0].addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ar_btn_vals0ActionPerformed(evt);
}
});
break;
case 1:
ar_btn_vals[1].addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ar_btn_vals1ActionPerformed(evt);
}
});
break;
}
}
}
private void ar_btn_vals0ActionPerformed(java.awt.event.ActionEvent evt) {
JFrame frm_val0change = new JFrame();
String newval = JOptionPane.showInputDialog(frm_val0change, "Enter new Button 1 Value");
ar_str_vals[0] = newval;
constructor();
}
private void ar_btn_vals1ActionPerformed(java.awt.event.ActionEvent evt) {
JFrame frm_val1change = new JFrame();
String newval = JOptionPane.showInputDialog(frm_val1change, "Enter new Button 2 Value");
ar_str_vals[1] = newval;
constructor();
}
public static void main(String[] args) {
Wtf frame = new Wtf();
}
}
I'm aware that this isn't as efficient as it could be, but I've got limited time to finish this and I have absolutely no idea why this isn't working properly.
This is also my first time asking a question, so please have mercy if I've formatted anything wrong.
As MadProgrammer said, all I had to do was update the button text in my action listener instead of calling the constructor again.

Create a Method to add components in Selected JTabbedPane

I am a newbie, and I have already passed some days to get the idea, but could not solve it, if anyone can help me.
I have main two JPanel in one JFrame. I have some buttons in the first panel. I have One method to add a panel to theJTabbedPane by calling another method to create that JPanels then add it to the Tab.
I want a method which will add any buttons/components to the Selected tab which I want whenever I click the button from the first panel.
How can I do this. I can post those three method's code here if anyone wish to help me. Thanks in advance.
The first code add new tabs to the JTabbedPane,
private class TabPlus implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JPanel panel = CreateSlice();
String title = "Slice " + String.valueOf(pane.getTabCount());
pane.insertTab(title, null, panel, null, pane.getTabCount() - 1);
}
}
The second code is for selecting the tabs,
private class TabSelect implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
JTabbedPane source = (JTabbedPane) e.getSource();
if (source.getSelectedComponent() != null) {
int index = source.getSelectedIndex();
System.out.print(index);
}
}
}
This creates the JPanel to be added to the JTabbedPane,
public JPanel CreateSlice() {
JPanel Slice = new JPanel();
Slice.setPreferredSize(new Dimension(550, 600));
return Slice;
}
The buttons are in another Panel with their own action.
GUI Image
You can add a panel with butttons this way:
public JPanel CreateSlice() {
JPanel Slice = new JPanel();
Slice.setPreferredSize(new Dimension(550, 600));
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(new JButton("dumpButton"));
buttonsPanel.setVisible(false);
Slice.add(buttonsPanel);
return Slice;
}
And whenever a selection occurs set the visibility of buttonsPanel to true.
I think, I found one way to do this, My index variable int index = source.getSelectedIndex(); must be public variable, then in Action event of the buttons from another tab will add component to this selected JTabbedPane.
In my case I introduced and ArrayList of panel (network_slices), and every time I am adding a panel to the JTabbedPane, it is also adding to the ArrayList. then I called the panel from the ArrayList by using the index of selected JTabbedPane. Here is the part of the code.
private class TabSelect implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
JTabbedPane source = (JTabbedPane) e.getSource();
if (source.getSelectedComponent() != null) {
index = source.getSelectedIndex();
System.out.print(index);
}
}
}
private class AddTab implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Slice panel = new Slice();
panel.setPreferredSize(new Dimension(550, 600));
String title = "Slice " + String.valueOf(pane.getTabCount());
pane.insertTab(title, null, panel, null, pane.getTabCount() - 1);
network_slices.add(panel);
}
}
private class AddNetworkFuncitons implements ActionListener {
public void actionPerformed(ActionEvent e) {
String buttonselected = (String) e.getActionCommand();
JButton button = new JButton(buttonselected);
network_slices.get(index).add(button).setVisible(true);
System.out.print(buttonselected);
}
}

Add Integer to JList in java

Im making a jframe with two components. A list and a button. The list starts at 0 and everytime i press the button it increases by 1. So if i press the button, the value in the jlist changes from 0 to 1.
My question is, how can I add an integer to a jlist? (i tried the setText method just in case - only works for Strings)
Thanks
EDIT: PART OF MY CODE (ActionListener)
increase.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
counter++;
System.out.println(counter);
listModel.addElement(counter);
// listModel.clear();
}
});
I'm assuming that you want to add an int item to the JList, meaning a new int pops up in the list's display each time the button is pushed. You can create a JList<Integer> and add Integers (or boxed ints) to the JList's model, usually using listModel.addElement(myInteger).
If you need to clear previous elements, do so before adding the element, not after. For example,
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Foo2 extends JPanel {
private DefaultListModel<Integer> dataModel = new DefaultListModel<>();
private JList<Integer> intJList = new JList<>(dataModel);
public Foo2() {
add(new JScrollPane(intJList));
intJList.setFocusable(false);
add(new JButton(new AbstractAction("Add Int") {
private int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
dataModel.clear(); // if you need to clear previous entries
dataModel.addElement(count);
count++;
}
}));
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Foo2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Foo2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Why is the focus never lost from my component when I press the JFrame?

I have a problem with the focus listener implemented by CustomTextField class. The focus listener is only called when another Swing component is getting the focus. But If I move the JFrame istelf by dragging it with the mouse, the focusLost() method is never called (in other words, it doesn´t seem that the focus is shifting from CustomTextField to JFrame).
EDIT: The solution of my question is below:
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class ScrollFocus extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ScrollFocus();
}
});
}
public ScrollFocus() {
this.setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<String> values = new Vector<>();
values.add("a");
values.add("b");
values.add("c");
values.add("d");
values.add("e");
JComboBox<String> comboBox = new JComboBox<>(values);
JScrollPane scrollPane = new JScrollPane(comboBox);
this.add(scrollPane, BorderLayout.NORTH);
CustomTextField customTextField = new CustomTextField();
this.add(customTextField, BorderLayout.CENTER);
JButton button = new JButton("press");
final JPopupMenu menu = new JPopupMenu("Menu");
menu.add(new JMenuItem("Test"));
button.setComponentPopupMenu(menu);
this.add(button, BorderLayout.SOUTH);
pack();
setVisible(true);
}
class CustomTextField extends JTextField implements FocusListener {
private CustomPopup customPopup = new CustomPopup();
public CustomTextField() {
this.addFocusListener(this);
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "VK_UP");
this.getActionMap().put("VK_UP", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
setPopupSize();
customPopup.show(CustomTextField.this, CustomTextField.this.getX(), CustomTextField.this.getY() + CustomTextField.this.getHeight());
customPopup.setSelectedIndex(0);
}
});
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "VK_DOWN");
this.getActionMap().put("VK_DOWN", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
setPopupSize();
customPopup.show(CustomTextField.this, CustomTextField.this.getX(), CustomTextField.this.getY() + CustomTextField.this.getHeight());
customPopup.setSelectedIndex(0);
}
});
}
public void setPopupSize() {
customPopup.setPopupSize(new Dimension(this.getWidth(), 110));
}
#Override
public void focusGained(FocusEvent e) {
}
#Override
public void focusLost(FocusEvent e) {
}
class CustomPopup extends JPopupMenu {
String[] values = new String[]{"Value1", "Value2", "Value3", "Value4", "Value5", "Value6", "Value7",
"Value8","Value9", "Value10", "Value11", "Value12", "Value13", "Value14", "Value15", "Value16",};
JList<String> list = new JList<>(values);
JScrollPane scrollPane = new JScrollPane(list);
public int index = 0;
public CustomPopup() {
this.setLayout(new GridLayout(0,1));
this.add(scrollPane);
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
if(customPopup.index > 0)
customPopup.setSelectedIndex(--customPopup.index);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
if(customPopup.index < customPopup.getListSize()-1)
customPopup.setSelectedIndex(++customPopup.index);
}
}
});
this.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
index=0;
}
});
pack();
}
public void setSelectedIndex(int index) {
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
requestFocus();
}
public int getListSize() {
return values.length;
}
}
}
}
//customPopup.setVisible(true);
customPopup.show((JComponent)e.getSource(), 0, 20);
You should be using the show(...) method to show the popup. This must add some listeners to the popup so you will no longer need the FocusListener on the text field.
However, now this is a different problem. The text field loses focus so the Action never get invoked. That would be ok, but the JList never gains focus so it doesn't respond to the up/down keys unless you click on the list box first. I'm not sure what the problem is here.
Maybe you can try to make the popup, scrollpane and list all non-focusable so that focus remains on the text field?
'Focus', which is admittedly a slightly ambiguous term, generally applies to a component, not to an entire window. We think of the "window with focus", but I think what we really mean is "the current window, the one which contains the focus." I would not expect focus_lost to be called if I moved the window (aka JFrame) itself.
Another way to think of it; if I had a text field, clicked in it, and typed a letter or two, I would see those letters in that text field. If I then moved the window slightly and typed another letter or two, I would still expect those letters to appear in that field. It still has focus, and never lost it.

JComboBox on a JPopupMenu

I'm trying to use a compound Swing component as part of a Menu.
Everything works just fine, apart from one detail: The component contains JComboBoxes and whenever the user clicks on one of them to open its dropdown, the dropdown opens but the menu disappears. Is it possible to make the menu stay open when a JComboBox is clicked?
I sub-classed JMenu. This is the corresponding code:
public class FilterMenu extends JMenu {
public FilterMenu(String name) {
super(name);
final JPopupMenu pm = this.getPopupMenu();
final FilterPanel filterPanel = new FilterPanel(pm) {
#Override
public void updateTree() {
super.updateTree();
pm.pack();
}
};
pm.add(filterPanel);
}
}
FilterPanel is the custom compound component. The pm.pack() is called to adapt the size of the JPopupMenu when the filterPanel changes in size.
Thanks for your help
are you meaning this bug
import javax.swing.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setVisible(true);
String[] list = {"1", "2", "3", "4",};
JComboBox comb = new JComboBox(list);
final JPopupMenu pop = new JPopupMenu();
pop.add(comb);
frame.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed");
pop.show(e.getComponent(), e.getX(), e.getY());
}
});
}
}
Look at Jide OSS' PopupWindow. This provides an easy-to-use solution for this problem. Works fine for me.
Javadoc is here.

Categories

Resources