JOptionPane.showConfirmDialog with a JScrollPane and a maximum size - java

I was trying to make a JFrame with a JScrollPane containing hundreds of JRadioButtons and two JButtons below (OK and Cancel). Finally I discovered the JOptionPane.showConfirmDialog(...) method.
It seems to be perfect for what I want : From a first JFrame, open a "window" with a Scroll containing my radio buttons and get the selected one in my first JFrame when I click on "OK".
However, when the showConfirmDialog appears, there is no JScrollPane, and we cannot see the bottom of the window (there are hundreds of radio buttons). So :
I tried to call JOptionPane.showConfirmDialog(myScrollPane) instead of adding the JScrollPane to a JPanel and call the method with a JPanel... it didn't work
I tried to initialize a JOptionPane object, then set its maximum size, then call the method showConfirmDialog with the initialized object but it doesn't work because "the method must be called in a static way".
So I need your help, here is my code, and I don't understand what is wrong and why I don't have a scroll with my radio buttons in the confirm dialog.
public void buildMambaJobPathWindow(ArrayList<String> list) {
ButtonGroup buttonGroup = new ButtonGroup();
JPanel radioPanel = new JPanel(new GridLayout(0,1));
for(int i=0; i<list.size(); i++) {
JRadioButton radioButton = new JRadioButton(list.get(i));
buttonGroup.add(radioButton);
radioButton.addActionListener(this);
radioButton.setActionCommand(list.get(i));
radioPanel.add(radioButton);
}
JScrollPane myScrollPane = new JScrollPane(radioPanel);
myScrollPane.setMaximumSize(new Dimension(600,600));
JOptionPane.showConfirmDialog(null, myScrollPane);
}
// Listens to the radio buttons
public void actionPerformed(ActionEvent e) {
String result = e.getActionCommand();
}
Thank you for your time.

As shown here, you can override the scroll pane's getPreferredSize() method to establish the desired size. If the content is larger in either dimension, the corresponding scroll bar will appear as needed.
JScrollPane myScrollPane = new JScrollPane(radioPanel){
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
};
JOptionPane.showConfirmDialog(null, myScrollPane);

Related

JOptionPane always returning -1

I want to double check the delete operation to prevent accidental deletion.
(Here the Yes button would only be enabled if the checkbox is checked.)
But both Yes and No Buttons are returning -1.
This is a snippet of my program.
public class class1 extends javax.swing.JInternalFrame {
JCheckBox cbConfirmDelete;
JPanel outer = new JPanel(new BorderLayout());
final JButton btnYes = new JButton("Yes");
final JButton btnNo = new JButton("No");
public class1() {
......
//Button btnYes ActionListener for JOptionPane
btnYes.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane((JComponent) e.getSource());
pane.setValue(btnYes);
}
});
//Button btnNo ActionListener for JOptionPane
btnNo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane((JComponent) e.getSource());
pane.setValue(btnNo);
}
});
//layout for JOptionPane
JPanel nested1 = new JPanel();
nested1.add(cbConfirmDelete);
JPanel nested2 = new JPanel();
nested2.add(btnYes);
nested2.add(btnNo);
outer.add(nested1, BorderLayout.NORTH);
outer.add(nested2, BorderLayout.CENTER);
}
protected JOptionPane getOptionPane(JComponent parent) {
JOptionPane pane = null;
if (!(parent instanceof JOptionPane)) {
pane = getOptionPane((JComponent) parent.getParent());
} else {
pane = (JOptionPane) parent;
}
return pane;
}
private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {
int dialogResult = JOptionPane.showOptionDialog(null, "Are you sure you want to Delete the Reference ?", "Delete Reference", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[]{outer}, btnYes);
System.out.println("DialogResult: " + dialogResult);
}
}
The Output DialogResult is always -1. Why is that happening ?
If I pass the following object in JOptionPane it works fine..
new Object[]{cbConfirmDelete, btnYes, btnNo}
But this is not working
new Object[]{outer}
I see a couple of problems here. Since you're creating a Yes/No option dialog, your Object[] array should contain two, and only two, components that correspond to yes or no.
For your example that works, your Object[] array contains the checkbox, the yes button, and the no button. That's one too many components. When you set the pane value in the yes or no action listener, you're setting it to 1 or 2 instead of 0 or 1, since positionally, those components are the second and third. This isn't necessarily a big problem, but usually when you return from a yes/no dialog box, you check for JOptionPane.YES_OPTION (0) or JOptionPane.NO_OPTION (1) to see if the user chose yes or no. In your scenario, you're going to have to check for 1 or 2 since the checkbox is component 0.
For your non-working scenario, the problem is that your object array only contains one object, the outer panel containing the checkbox and the yes/no buttons. Technically what's happening is that you're telling the option pane that there's only one selectable component, a JPanel. Calling pane.setValue() with any component other than the outer panel will have no effect, since the pane's selection value is -1 (uninitialized value) to begin with, and it will only change if you call setValue(outer).

How can I click on a picture and then make that picture appear in a new JFrame? [duplicate]

This question already has answers here:
How to find JLabel that was clicked and show ImageIcon from it?
(2 answers)
Closed 7 years ago.
I have a JFrame opening with 12 different pictures. I want to click on one and then in the new JFrame, show that same picture. In my code, shirts is my JFrame with the 12 pictures and I want the clicked picture to appear in the new JFrame called sizes. I made an ArrayList of type JLabel called select. Here is my code:
final JFrame shirts = new JFrame("T-shirts");
JPanel panel = new JPanel(new GridLayout(4, 4, 3, 3));
for (int i = 1; i < 13; i++) {
l = new JLabel(new ImageIcon("T-shirts/"+i+".jpg"), JLabel.CENTER);
l.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
l.setFont(l.getFont().deriveFont(20f));
panel.add(l);
select.add(l);
}//end of for loop
panel.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
sizes = new JFrame("Shopping");
sizes.setVisible(true);
sizes.setSize(500, 500);
sizes.setLocation(100,200);
shirts.dispose();
for(int i=0; i<12; i++){
if(e.getSource()==select.get(i)){
JLabel addition = newJLabel(newImageIcon(select.get(i).getText()));
//sizes.add(select.get(i));//Picture isn't added!!
}//end of if
}//end of for
}//end of method
});//end of listener
shirts.setContentPane(panel);
shirts.setSize(1000, 1000);
shirts.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
shirts.setVisible(true);
Start with How to Write a Mouse Listener.
Basically, you want to register a MouseListener with the JLabel which represents your picture and implement it's mouseClicked method.
You then want to get the Icon property of the JLabel that was clicked and pass that to your new frame, which you can simply use to set the Icon property of another JLabel
Something like...
addition.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
JLabel label = (JLabel) e.getComponent();
Icon icon = label.getIcon();
// Create new frame and pass it the icon value
}
});
as an example
You might also like to take a look at The Use of Multiple JFrames, Good/Bad Practice? and consider using either a CardLayout or JDialog instead of another JFrame ... which could become messy
You can use a JButton and make it look like a JLabel:
JButton button = new JButton( new ImageIcon("..." ));
button.setBorderPainted( false );
button.setContentFilled( false );
button.setFocusPainted( false );
button.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
Icon icon = button.getIcon();
// do something with the Icon.
}
});
Then you can add an ActionListener to the button.
An ActionListener is more reliable than using a MouseListener and handling the mouseClicked event. The mouseClicked event is only generated when a mousePressed and mouseReleased event is generated at the same mouse point. So if the mouse moves by even pixel between the two event you will not get a mouseClicked event which users think is a random problem.
Try making each picture a JButton, or at least placing an invisible button behind each picture. Then, when they are pressed in the ActionListener extended class, have the new JFrame be created, with the picture large.

Java changing an existing component

I am trying to change a component from a JLabel to JComboBox when another option is added but for some reason the panel is not updating.
SSCCE:
public class SwitchComponent {
public static void main(String[] args) {
JPanel panel = new JPanel();
JComponent component = new JLabel("This is a test");
panel.add(component);
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Testing..");
comboBox.addItem("1.. 2.. 3..");
component = comboBox;
// I have tried with only one of the below lines and without any also...
// Doesn't seem to have an effect.
// I've also tried invoking the below methods on the panel instead.
component.revalidate();
component.repaint();
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
}
}
Why is this happening? Shouldn't panel be referencing component such that any changes to component are reflected via panel?
Do I really have to completely reassemble the panel when the component changes?
When click YES/NO button on JOptionPane, JOptionPane will close.
We need to add the JComboBox to Panel again and use JOptionPane to show the Panel again in your code.
Have a try with this:
public class SwitchComponent {
public static void main(String[] args) {
JPanel panel = new JPanel();
JComponent component = new JLabel("This is a test");
panel.add(component);
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
panel.remove(component);
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Testing..");
comboBox.addItem("1.. 2.. 3..");
panel.add(comboBox);
// I have tried with only one of the below lines and without any also...
// Doesn't seem to have an effect.
// I've also tried invoking the below methods on the panel instead.
panel.revalidate();
panel.repaint();
JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_OPTION,
JOptionPane.PLAIN_MESSAGE);
}
}
I.e. the label could be second in a series of three, I would want the combo box to remain second when the component is changed to the combo box. Hence why I was trying to change the reference
Use a Card Layout. It will replace a component at the same location.

adding components dynamically in a JPanel

how can i add components dynamically in a jpanel?
I am having add button when i click the button the components should be added to the JPanel.
my question is that adding a textfield and button to jpanel when i click on the add button the user can click on the add button any number of times according to that i have to add them to the jpanel. i have added to scrollerpane to my jpanel,and jpanel layout manager is set to null.
Just as you always do, except that you have to call:
panel.revalidate();
when you are done, since the container is already realized.
Use an ActionListener, you can use an anonymous class like this:
JPanel myJPanel = new JPanel();
...
b = new Button("Add Component");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JLabel someLabel = new JLabel("Some new Label");
myJPanel.add(someLabel);
myJPanel.revalidate();
}
});

Activity Stream- Producing X amount of objects in a panel on app load

Just wondering if you could help wanting to produce an activity stream in Java, the idea was to have a JLabel and text area followed by a divider be displayed on a screen and then repeated X amount of times according to what data was in a database.
What I was wondering is how could I possibly repeat the placing the jlabel, text area, and diveder on the screen above the last rendered objects on the fly and all displayed correctly no matter the size of the text area of each set of object sort of like the image below.
Hope I made it clear as I could thanks
Just provide your own version of a JPanel containing all these things and place them in a scrollpane that will care about having a long list of these panels..
class MyPanel extends JPanel
{
ImageIcon icon;
JTextArea textArea;
MyPanel(ImageIcon icon, String text)
{
this.icon = icon;
this.setPreferredSize(/*max size of your panel */)
textArea = new JTextArea(10, 50);
textArea.append(text);
//the default manager will be a flow layout for single jpanels
this.add(icon);
JScrollPane sp = new JScrollPane(textArea);
sp.setPreferredSize(new Dimension(/* size of your text label */));
this.add(new JScrollPtextArea);
}
}
class MyContainer extends JFrame
{
JPanel container;
JScrollPane spContainer;
MyContainer()
{
container = new JPanel()
container.setGridLayout(100,1); //100 elements max
spContainer = new JScrollPane(container);
spContainer.setPreferredSize(/* max size of whole thing */)
this.add(spContainer);
pack();
}
void addElement(MyPanel panel)
{
container.add(panel);
this.pack();
}
}
It's not fully working (I just wrote it) but it should give you the idea..

Categories