JTree refresh without collapsing - java

I have a problem when refreshing a JTree instance. See the following code:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class ItemTest {
private JFrame frame;
private DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
private JTree tree = new JTree(root);
private JButton button = new JButton("Rebuild");
private String[] array = new String[] { "name", "first_name", "middle_name", "last_name"};
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
ItemTest window = new ItemTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ItemTest() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 523, 349);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scrollBar = new JScrollPane();
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(scrollBar, GroupLayout.PREFERRED_SIZE, 200, GroupLayout.PREFERRED_SIZE)
.addComponent(button, GroupLayout.PREFERRED_SIZE, 85, GroupLayout.PREFERRED_SIZE)
.addContainerGap(412, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(22)
.addComponent(scrollBar, GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)
.addComponent(button, GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE)
.addContainerGap())
);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
root.add(new DefaultMutableTreeNode("Row 4"));
((DefaultTreeModel) tree.getModel()).nodeChanged(root);
}
});
for(String string : array) {
root.add(new DefaultMutableTreeNode(string));
}
scrollBar.setViewportView(tree);
frame.getContentPane().setLayout(groupLayout);
}
}
If we run this code, and expand the "Root" node. We will see 4 nodes in it. If we click the button "Rebuild", the tree won't update it's self. The weird thing is, if we don't expand the "Root" node at the begin (so just start the application) and click the button, and after that we expand the "Root" node, the new row is added. Does anyone knows how to refresh this tree without collapsing, because nodeChanged doesn't seem to work when you expand the "Root" node at the begin.
Note: I have to accomplish this without using insertNodeInto.

You must notify the listeners that a node was inserted:
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
root.add(new DefaultMutableTreeNode("Row 4"));
((DefaultTreeModel) tree.getModel()).nodesWereInserted(
root, new int[]{root.getChildCount()-1});
}
});

Related

frame.dispose() not working. Possibly an instantiating object problem?

I have a game that has a MainUI class, a GameClass and a SettingsClass. The game works fine except when I click "Restart" or "Help" which takes me to another JFrame and then returns back to the MainUI by a click of a button. But, when that happens, the MainUI class does not dispose of itself when it should. I believe it has to do with instantiating the MainUI class again when I leave and come back from settings but I'm but sure how to fix it.
This is the code I'm using to dispose of the MainUI frame and open a new JFrame:
private final JFrame mainFrame;
mainFrame.dispose(); //the mainFrame variable is passed in the constructor since it's trying to dispose of the MainUI
EndingPage endingPage = new EndingPage(); //open ending page
endingPage.setVisible(true);
This is an example of part of the code for one of the buttons in the settings class
restart.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
MainUI.started=false;
mainFrame.dispose();
TitlePage title = new TitlePage();
title.setVisible(true);
}
});
When one of those buttons are clicked, another JFrame is opened accordingly. To go back to the MainUI this is run:
this.dispose();
MainUI main = new MainUI();
main.setVisible(true);
For more clarification, the second code is run when the user clicks the settings button. Then, the last code is run to get back to the JFrame it already was at. When the user wins the first code is run. But the issue is sometimes the mainFrame.dispose(); in the first code does not work. Any help is appreciated! If you need to see other code please tell me! I'm stuck.
EDIT:
This is the MainUI (there is a timer because I want to delay before the action)
package stackoverflowcode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class MainUI extends javax.swing.JFrame {
/**
* Creates new form MainUI
*/
public MainUI() {
initComponents();
GameClass game = new GameClass(this, end);
SettingsClass settings = new SettingsClass(restart, this);
Timer timer;
private javax.swing.JButton end;
private javax.swing.JButton restart;
ActionListener action = new ActionListener(){
#Override
public void actionPerformed(ActionEvent event)
{
game.openEnd();
}
};
timer= new Timer (1000,action);
timer.start();
settings.settings();
}
private void initComponents() {
restart = new javax.swing.JButton();
end = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
restart.setText("SETTINGS");
end.setText("END");
javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(151, 151, 151)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(end)
.addComponent(restart))
.addContainerGap(168, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(120, 120, 120)
.addComponent(restart)
.addGap(48, 48, 48)
.addComponent(end)
.addContainerGap(86, Short.MAX_VALUE))
);
pack();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainUI().setVisible(true);
}
});
}
}
SettingsClass
package stackoverflowcode;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class SettingsClass {
JButton restart;
JFrame mainFrame;
public SettingsClass(JButton restart, JFrame mainFrame){
this.restart=restart;
this.mainFrame=mainFrame;
}
public void settings() {
restart.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
mainFrame.dispose();
TitlePage title = new TitlePage();
title.setVisible(true);
}
});
}
}
TitlePage
package stackoverflowcode;
public class TitlePage extends javax.swing.JFrame {
/**
* Creates new form TitlePage
*/
public TitlePage() {
initComponents();
private javax.swing.JButton Play;
}
private void initComponents() {
Play = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
Play.setText("PLAY");
Play.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
PlayActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(134, 134, 134)
.addComponent(Play)
.addContainerGap(209, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(129, 129, 129)
.addComponent(Play)
.addContainerGap(148, Short.MAX_VALUE))
);
pack();
}
private void PlayActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
this.dispose();
MainUI main = new MainUI();
main.setVisible(true);
}
public static void main(String args[]){
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TitlePage().setVisible(true);
}
});
}
}
GameClass
package stackoverflowcode;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class GameClass {
private final JFrame mainFrame;
private final JButton endButton;
public GameClass(JFrame mainFrame, JButton endButton){
this.mainFrame=mainFrame;
this.endButton=endButton;
}
public void openEnd(){
endButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
mainFrame.dispose(); //the mainFrame variable is passed in the constructor since it's trying to dispose of the MainUI
TitlePage endingPage = new TitlePage(); //open title page
endingPage.setVisible(true);
}
});
}
}

Counter reset not working in Java

In my program it has two JButton with name Start and Reset to 0 and one JTextField and one JLabel. When I click to Start JButton number of times its show the result in JTextField.
If count number is equal to 1 it show message Start in JLabel and when count is greater than 1 it show the Reset to 0 in JLabel. But the problem is when I click on Reset to 0 JButton it reset to 1 but it not showing message Reset to 0 in JLabel?
Program is here:
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import com.alee.laf.rootpane.WebFrame;
import java.awt.Font;
import javax.swing.SwingConstants;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
public class Search {
private WebFrame frame;
private JTextField textField;
private JButton btnResetTo;
private JButton btnNewButton;
private int count;
private JLabel lblNewLabel;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Search window = new Search();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Search() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new WebFrame();
frame.setBounds(100, 100, 296, 374);
frame.setDefaultCloseOperation(WebFrame.EXIT_ON_CLOSE);
btnNewButton = new JButton("Start");
btnNewButton.addMouseListener(new MouseAdapter() {
private int Qnty;
#Override
public void mouseClicked(MouseEvent e) {
count=e.getClickCount();
textField.setText(Integer.toString(count));
Qnty=Qnty+count;
if(Qnty==1)
lblNewLabel.setText("Start");
else if(Qnty>1)
{
lblNewLabel.setText("Reset");
}
}
});
textField = new JTextField();
textField.setFont(new Font("Tahoma", Font.BOLD, 40));
textField.setHorizontalAlignment(SwingConstants.CENTER);
textField.setColumns(10);
btnResetTo = new JButton("Reset to 0");
btnResetTo.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
count=e.getClickCount();
count=0;
}
});
lblNewLabel = new JLabel("");
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 15));
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(lblNewLabel, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)
.addGroup(Alignment.LEADING, groupLayout.createSequentialGroup()
.addComponent(btnNewButton, GroupLayout.PREFERRED_SIZE, 88, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 36, Short.MAX_VALUE)
.addComponent(btnResetTo, GroupLayout.PREFERRED_SIZE, 136, GroupLayout.PREFERRED_SIZE))
.addComponent(textField, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(25)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
.addComponent(btnResetTo, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnNewButton, GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, 69, GroupLayout.PREFERRED_SIZE)
.addGap(31)
.addComponent(lblNewLabel, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE)
.addGap(73))
);
frame.getContentPane().setLayout(groupLayout);
}
}
Use a ActionListener instead of MouseListener on your buttons - buttons can be trigged in more ways then just clicking on them. See How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listener for more details
When reset is called, you actually need to change the components, like you did with btnNew - the variables aren't magically linked to the components
Maybe like
btnResetTo = new JButton("Reset to 0");
btnResetTo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
count = 0;
textField.setText(Integer.toString(count));
lblNewLabel.setText("Start");
}
});

JScrollPane and autoscroll: Disturbing scrolling behavior

I am writing an application which uses a JScrollPane. In this JScrollPane I want to automatically display search results, This means, that I have to dynamically add and remove the results within the JScrollPane. The results are realised as JTextArea, which are embeded within a GridBagLayout.
When there is a high number of search results, the JScrollPane automatically scrolls to the bottom (It should be at the top). I have solved it with a solution I found here. The problem hereby is, that you can see, how it scrolls back to the top. Is it possible to remove this behaviour?
The following things I found out:
I have to remove the previous search results to display the new ones. If I don't remove the previous ones, it displays correctly.
It neither solves the prblem wgeb I update the JScrollPane every tune after adding arow nor when updating only after adding all rows.
The best would be to just disable autoscroll. I have created an executable example to demonstrate this behavior. When clicking the button "Add Row", 500 rows are added. When clicking it several times, it becomes very clear.
Thank you very much for your help!
import java.awt.GridBagConstraints;
import javax.swing.JTextArea;
public class ScrollPaneTest extends javax.swing.JFrame {
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
/**
* Creates new form ScrollPaneTest
*/
public ScrollPaneTest() {
initComponents();
}
/**
* Adds a new row.
* #param index The index of the new row.
*/
private void addRow(int index) {
JTextArea row = new JTextArea("Area " + index);
row.setEditable(false);
row.setBorder(null);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = index;
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
jPanel2.add(row, gridBagConstraints);
}
/**
* Initializes the components.
*/
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jPanel1 = new javax.swing.JPanel();
jPanel2 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 400));
jScrollPane1.setViewportView(jPanel1);
jPanel1.setLayout(new java.awt.BorderLayout());
jPanel2.setLayout(new java.awt.GridBagLayout());
jPanel1.add(jPanel2, java.awt.BorderLayout.NORTH);
jScrollPane1.setViewportView(jPanel1);
jButton1.setText("Create Rows");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addGap(148, 148, 148)
.addComponent(jButton1)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 245, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton1)
.addGap(0, 21, Short.MAX_VALUE))
);
pack();
}
/**
* Creates 500 new rows.
* #param evt
*/
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jPanel2.removeAll();
for(int i = 0; i < 1000; i++) {
addRow(i);
}
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
jScrollPane1.getVerticalScrollBar().setValue(0);
}
});
jPanel2.validate();
jPanel2.repaint();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ScrollPaneTest().setVisible(true);
}
});
}
}
UPDATE 1
I removed the lambda expressions. Hopefully it should be now compileable also with < Java 8.
UPDATE 2
The problem with the disturbing scrolling behavior has been solved by replacing
jPanel2.validate();
jPanel2.repaint();
with
jScrollPane1.validate();
jScrollPane1.repaint();
Nevertheless, both answers to this question can be very helpful in some other cases and should be given attention.
One way to achieve this is to have a custom JViewPort for your scrollpane. This custom viewport overrides setViewPosition and uses a flag to prevent the scroll, or not.
Here is an example of such code, before changing the content of the textarea, we "lock" the viewport to prevent scrolling, and we unlock it later:
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class TestNoScrolling {
private int lineCount = 0;
private LockableViewPort viewport;
private JTextArea ta;
private final class LockableViewPort extends JViewport {
private boolean locked = false;
#Override
public void setViewPosition(Point p) {
if (locked) {
return;
}
super.setViewPosition(p);
}
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
}
protected void initUI() {
JFrame frame = new JFrame("test");
ta = new JTextArea(5, 30);
JScrollPane scrollpane = new JScrollPane();
viewport = new LockableViewPort();
viewport.setView(ta);
scrollpane.setViewport(viewport);
frame.add(scrollpane);
frame.pack();
frame.setVisible(true);
Timer t = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
viewport.setLocked(true);
ta.append("Some new line " + lineCount++ + "\n");
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
viewport.setLocked(false);
}
});
}
});
t.setRepeats(true);
t.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestNoScrolling().initUI();
}
});
}
}
You could simply set the Caret position to the start position (0), for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ScrollNoMore {
public static void main(String[] args) {
new ScrollNoMore ();
}
public ScrollNoMore () {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
private JScrollPane sp;
private Random rnd = new Random();
private boolean initalised = false;
public TestPane() {
setLayout(new BorderLayout());
ta = new JTextArea(20, 40);
sp = new JScrollPane(ta);
add(sp);
Timer timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
long value = rnd.nextLong();
ta.append(String.valueOf(value) + "\n");
if (!initalised) {
ta.setCaretPosition(0);
initalised = true;
}
}
});
timer.start();
}
}
}
This will only set it the first time the Timer runs, this means that if you move the Caret or scroll position for some reason, it won't "flick" back. You could set up a series of states where by if the user moved the current view, it didn't effect the scrolling, but could be reset as required.

Java - set a size to JDialog

I have a strange problem, i did two class (They are very similar), but in the first Class the setPreferredSize method, works in the other not; so i have to use (in this class) setSize() method. And this is really strange. I post my code:
In this class it works well
package StudentNotes;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Timer;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import StudentNotes.TextPrompt.Show;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
public class CreateCourse extends JDialog {
private JTextField tFieldCourseName;
/**
* Create the dialog.
*/
public CreateCourse(JDialog mainFrame, final StudApp studAppObj) {
super(mainFrame, ModalityType.APPLICATION_MODAL);
setPreferredSize(new Dimension(330, 200)); //it works
setTitle("Create a course");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setAlwaysOnTop(true);
tFieldCourseName = new JTextField();
tFieldCourseName.setFont(new Font("Tahoma", Font.BOLD, 14));
tFieldCourseName.setColumns(10);
TextPrompt tp = new TextPrompt("Course name", tFieldCourseName);
tp.changeStyle(Font.ITALIC);
tp.setShow(Show.ALWAYS);
tp.setForeground(Color.GRAY);
final JLabel lblAllertcourse = new JLabel("");
lblAllertcourse.setHorizontalAlignment(SwingConstants.CENTER);
JButton btnAddCourse = new JButton("Add course");
btnAddCourse.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
javax.swing.Timer t = new javax.swing.Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
lblAllertcourse.setText("");
}
});
String nameCourse = tFieldCourseName.getText();
ArrayList<Corso> courses = studAppObj.getCorsi();
if (nameCourse.equals("")) {
lblAllertcourse.setText("Insert a valid name course!");
t.setRepeats(false);
t.start();
return;
}
for (Corso currentCourse : courses) {
if (currentCourse.name.toUpperCase().equals(nameCourse.toUpperCase())) {
lblAllertcourse.setText("This course already exist!");
t.setRepeats(false);
t.start();
return;
}
}
studAppObj.setCorsi(new Corso(), nameCourse);
lblAllertcourse.setText("Course added successfully");
t.setRepeats(false);
t.start();
}
});
GroupLayout groupLayout = new GroupLayout(getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(113)
.addComponent(btnAddCourse))
.addGroup(groupLayout.createSequentialGroup()
.addGap(103)
.addComponent(tFieldCourseName, GroupLayout.PREFERRED_SIZE, 119, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblAllertcourse, GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(46)
.addComponent(tFieldCourseName, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnAddCourse)
.addPreferredGap(ComponentPlacement.UNRELATED)
.addComponent(lblAllertcourse)
.addContainerGap(44, Short.MAX_VALUE))
);
getContentPane().setLayout(groupLayout);
pack();
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
}
in this other class setPreferredSize does not work, the JDialog doesnt have a size so it reamins small ( i can just see the title of the Dialog and not more).
package StudentNotes;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
public class EditCourse extends JDialog {
/**
* Create the dialog.
*/
public EditCourse(JDialog mainFrame, final StudApp studAppObj) {
super(mainFrame, ModalityType.APPLICATION_MODAL);
//I have to use setSize
// if i use setPreferredSize does not work
setSize(new Dimension(330, 200));
setTitle("Edit course");
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setAlwaysOnTop(true);
ArrayList<Corso> listCourses = studAppObj.getCorsi();
listCourses.toArray();
String[] listData = { "one", "two", "three", "four",
"five", "six", "seven" };
JList list = new JList(listData);
list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == true) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
int minIndex = lsm.getMinSelectionIndex();
int maxIndex = lsm.getMaxSelectionIndex();
for (int i=minIndex; i<=maxIndex; i++) {
if (lsm.isSelectedIndex(i)) {
System.out.println("hai selezionato l'indice nr. "+i);
}
}
}
}
});
JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setSize(new Dimension(118, 40));
GroupLayout groupLayout = new GroupLayout(getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(108)
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 108, GroupLayout.PREFERRED_SIZE)
.addContainerGap(108, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(21)
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 64, GroupLayout.PREFERRED_SIZE)
.addContainerGap(87, Short.MAX_VALUE))
);
getContentPane().setLayout(groupLayout);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
}
In the second class there's no call to pack() method and that's why the dialog remains "small":
public void pack()
Causes this Window to be sized to fit the preferred size and layouts
of its subcomponents. The resulting width and height of the window are
automatically enlarged if either of dimensions is less than the
minimum size as specified by the previous call to the setMinimumSize
method.
If the window and/or its owner are not displayable yet, both of them
are made displayable before calculating the preferred size. The Window
is validated after its size is being calculated.
You should also take a look to this topic: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

Dynamic child communication

Background: I have a JPanel (PanelCarga extends JPanel) that displays as many sub-JPanels (DatosArchivo extends JPanel) as files I wish to open (n DatosArchivo panels) in my program for diferent purposes. This DatosArchivos contains a "X" button that I wish it to closes this DatosArchivos panel and then informs to the corresponding PanelCarga that it have been closed so that can reorganize in his grid the remaining n-1 DatosArchivo panels.
Tha PanelCarga Class:
package gui;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.sql.SQLException;
import java.util.LinkedList;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import logica.Cargador;
public class PanelCarga extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextField textField;
private final JPanel panel = new JPanel();
/**
* Create the panel.
*/
public PanelCarga() {
JLabel lblArchivosA = new JLabel("Archivo (-s) a cargar");
textField = new JTextField();
textField.setEditable(false);
textField.setColumns(10);
final JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(panel);
panel.setLayout(new GridLayout(0, 2, 0, 0));
JButton btnAbrir = new JButton("Abrir");
btnAbrir.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFileChooser escoger = new JFileChooser();
escoger.setMultiSelectionEnabled(true);
int resultado = escoger.showOpenDialog(null);
File[] archivos = null;
String nombres = "";
if (resultado == JFileChooser.APPROVE_OPTION) {
archivos = escoger.getSelectedFiles();
for (int i = 0; i<archivos.length;i++){
if (i==0){
nombres = nombres + archivos [i].getName() ;
}else{
nombres = nombres + "; " +archivos [i].getName() ;
}
DatosArchivo datos = null;
try {
datos = new DatosArchivo();
} catch (SQLException e) {
JDialog error = new JDialog ();
error.setTitle("error");
JLabel mensaje = new JLabel(e.getMessage());
error.getContentPane().add(mensaje);
error.validate();
}
datos.textField_Ruta.setText(archivos[i].toString());
JTextField texto = new JTextField ();
texto.setBounds(10, 10, 100, 100);
panel.add(datos);
}
textField.setText(nombres);
panel.validate();
scrollPane.validate();
}
}
});
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(scrollPane, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblArchivosA)
.addGap(18)
.addComponent(textField, GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnAbrir)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(6)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblArchivosA)
.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnAbrir))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 423, Short.MAX_VALUE)
.addContainerGap())
);
setLayout(groupLayout);
}
public LinkedList <Cargador> getCargadores (){
LinkedList <Cargador> cargadores = new LinkedList <Cargador> ();
for (int i = 0; i < panel.getComponentCount(); i++){
cargadores.add(((DatosArchivo) panel.getComponent(i)).getCargador());
}
return cargadores;
}
public JPanel getPanel (){
return this.panel;
}
}
And the DatosArchivo Class:
package gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLException;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.BevelBorder;
import logica.Cargador;
import logica.Conector;
public class DatosArchivo extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public JTextField textField_Ruta;
private JTextField textField_Anio;
private JTextField textField_UbicacionNueva;
private String usuario = "rpatrizio";
private final JComboBox comboBox_Ubicacion ;
private JComboBox comboBox_Dia;
private JComboBox comboBox_mes;
/**
* Create the panel.
* #throws SQLException
*/
public DatosArchivo() throws SQLException {
setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
JPanel panel = new JPanel();
JLabel lblArchivo = new JLabel("Archivo:");
textField_Ruta = new JTextField();
textField_Ruta.setEditable(false);
textField_Ruta.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(lblArchivo)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_Ruta, GroupLayout.DEFAULT_SIZE, 190, Short.MAX_VALUE)
.addContainerGap())
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(lblArchivo)
.addComponent(textField_Ruta, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panel.setLayout(gl_panel);
JPanel panel_1 = new JPanel();
JLabel lblUbicación = new JLabel("Ubicaci\u00F3n");
textField_UbicacionNueva = new JTextField();
textField_UbicacionNueva.setEditable(false);
textField_UbicacionNueva.setColumns(10);
String [] ubicaciones = Conector.getUbicacion();
comboBox_Ubicacion = new JComboBox(ubicaciones);
comboBox_Ubicacion.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (comboBox_Ubicacion.getSelectedItem().toString().equals("Agregar Nueva")){
textField_UbicacionNueva.setEditable(true);
}else {
textField_UbicacionNueva.setEditable(false);
}
}
});
String [] dias = {"","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};
String [] meses = {"","enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"};
JPanel panel_2 = new JPanel();
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(panel, GroupLayout.DEFAULT_SIZE, 296, Short.MAX_VALUE)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 296, Short.MAX_VALUE)
.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 296, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 32, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE)
.addGap(16))
);
JLabel lblFecha = new JLabel("Fecha");
comboBox_Dia = new JComboBox(dias);
JLabel lblDe = new JLabel("de");
comboBox_mes = new JComboBox(meses);
JLabel lblDe_1 = new JLabel("de");
textField_Anio = new JTextField();
textField_Anio.setColumns(10);
JButton btnX = new JButton("X");
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
});
GroupLayout gl_panel_2 = new GroupLayout(panel_2);
gl_panel_2.setHorizontalGroup(
gl_panel_2.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_2.createSequentialGroup()
.addContainerGap()
.addComponent(lblFecha)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(comboBox_Dia, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblDe)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(comboBox_mes, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblDe_1)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(textField_Anio, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnX)
.addGap(49))
);
gl_panel_2.setVerticalGroup(
gl_panel_2.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_2.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel_2.createParallelGroup(Alignment.BASELINE)
.addComponent(lblFecha)
.addComponent(comboBox_Dia, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblDe)
.addComponent(comboBox_mes, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(lblDe_1)
.addComponent(textField_Anio, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(btnX))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panel_2.setLayout(gl_panel_2);
JButton button = new JButton("+");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (textField_UbicacionNueva.getText().equals("") || !textField_UbicacionNueva.isEnabled() || !comboBox_Ubicacion.getSelectedItem().equals("Agregar Nueva")){
String message = "Ubicación nueva no disponible";
JOptionPane.showMessageDialog(new JFrame(), message, "Dialog", JOptionPane.ERROR_MESSAGE);
}else{
}
}
});
GroupLayout gl_panel_1 = new GroupLayout(panel_1);
gl_panel_1.setHorizontalGroup(
gl_panel_1.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(6)
.addComponent(lblUbicación)
.addGap(5)
.addComponent(comboBox_Ubicacion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGap(11)
.addComponent(textField_UbicacionNueva, GroupLayout.PREFERRED_SIZE, 91, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(button)
.addContainerGap())
);
gl_panel_1.setVerticalGroup(
gl_panel_1.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(9)
.addComponent(lblUbicación))
.addGroup(gl_panel_1.createSequentialGroup()
.addGap(5)
.addGroup(gl_panel_1.createParallelGroup(Alignment.BASELINE)
.addComponent(comboBox_Ubicacion, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(textField_UbicacionNueva, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(button)))
);
panel_1.setLayout(gl_panel_1);
setLayout(groupLayout);
}
public Cargador getCargador(){
return new Cargador (this.getRuta(),this.getUbicacion(),this.getFecha(),this.getUsuario());
}
public String getFecha (){
return this.getAnio()+"-"+this.getMes()+"-"+this.getDia().toString()+" 00:00:00.000";
}
public String getUsuario (){
return this.usuario;
}
public String getRuta (){
return this.textField_Ruta.getText();
}
public String getAnio(){
return this.textField_Anio.getText();
}
public String getMes(){
String mes = null;
if (this.comboBox_mes.getSelectedItem().toString().equals("enero")){
mes = "01";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("febrero")){
mes = "02";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("marzo")){
mes = "03";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("abril")){
mes = "04";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("mayo")){
mes = "05";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("junio")){
mes = "06";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("julio")){
mes = "07";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("agosto")){
mes = "08";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("septiembre")){
mes = "09";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("octubre")){
mes = "10";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("noviembre")){
mes = "11";
}else if (this.comboBox_mes.getSelectedItem().toString().equals("diciembre")){
mes = "12";
}
return mes;
}
public String getDia(){
return this.comboBox_Dia.getSelectedItem().toString();
}
public String getUbicacion(){
if (this.comboBox_Ubicacion.getSelectedItem().toString().equals("Agregar Nueva")){
if (this.textField_UbicacionNueva.getText().equals("")){
return null;
}else {
return this.textField_UbicacionNueva.getText();
}
}else if (this.comboBox_Ubicacion.getSelectedItem().toString().equals("")){
return null;
}else {
return this.comboBox_Ubicacion.getSelectedItem().toString();
}
}
}
Thanks in advance
I'm not sure if there is any one best way to do this, but I see two possible ways:
One way is to allow outside classes to add an ActionListener to the btnX held in DatosArchivo by giving this class a public method for doing this. Something like:
public void addbtnXActionListener(ActionListener listener) {
btnX.addActionListener(listener);
}
Then the outside class can delete that JPanel from its display if it wishes. The advantage of doing it this way is that the DatosArchivo need know nothing about the gui that's holding it. When I did it this way, I also gave the DatosArchivo a public getBtnX() method to return the btnX JButton. This is so I can match the JButton obtained from the ActionListener's actionPerformed method's getSource method to be able to decide which DatosArchivo object to dispose.
For example:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo002 {
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo002");
frame.getContentPane().add(new PanelCarga2());
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();
}
});
}
}
#SuppressWarnings("serial")
class PanelCarga2 extends JPanel {
private static final Dimension PREF_SIZE = new Dimension(600, 400);
private JPanel datosArchivoContainer = new JPanel();
private BtnXListener btnXListener = new BtnXListener();
public PanelCarga2() {
JButton btnAbrir = new JButton("Abrir");
btnAbrir.addActionListener(new ActionListener() {
int index = 1;
public void actionPerformed(ActionEvent e) {
DatosArchivo2 datosArchivo2 = new DatosArchivo2(index);
datosArchivo2.addbtnXActionListener(btnXListener);
datosArchivoContainer.add(datosArchivo2);
datosArchivoContainer.revalidate();
index++;
}
});
JPanel topPanel = new JPanel();
topPanel.add(btnAbrir);
datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
setPreferredSize(PREF_SIZE);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
}
private class BtnXListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
Component[] components = datosArchivoContainer.getComponents();
for (int i = components.length - 1; i >= 0; i--) {
if (components[i] instanceof DatosArchivo2) {
DatosArchivo2 datoArchivo = (DatosArchivo2) components[i];
if (source.equals(datoArchivo.getBtnX())) {
datosArchivoContainer.remove(components[i]);
}
}
}
datosArchivoContainer.revalidate();
datosArchivoContainer.repaint();
}
}
}
#SuppressWarnings("serial")
class DatosArchivo2 extends JPanel {
private JButton btnX = new JButton("X");
public DatosArchivo2(int index) {
setPreferredSize(new Dimension(200, 200));
setBorder(BorderFactory.createEtchedBorder());
add(btnX);
add(new JLabel("Index: " + index));
}
public void addbtnXActionListener(ActionListener listener) {
btnX.addActionListener(listener);
}
public JButton getBtnX() {
return btnX;
}
}
Another way to do this is to give DatosArchivo a reference to its containing class and then having the DatosArchivo object handle its own deletion. The disadvantage to this is I believe that there is some increased cohesion. For this to work, I passed a reference of the containing PanelCarga into the DatosArchivo's constructor, and then gave PanelCarga a public removeDatosArchivo that the DatosArchivo method will call, passing itself as a parameter:
public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
datosArchivoContainer.remove(datosArchivo);
datosArchivoContainer.revalidate();
datosArchivoContainer.repaint();
}
This whole example program looks like:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo003 {
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo002");
frame.getContentPane().add(new PanelCarga3());
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();
}
});
}
}
#SuppressWarnings("serial")
class PanelCarga3 extends JPanel {
private static final Dimension PREF_SIZE = new Dimension(600, 400);
private JPanel datosArchivoContainer = new JPanel();
public PanelCarga3() {
JButton btnAbrir = new JButton("Abrir");
btnAbrir.addActionListener(new ActionListener() {
int index = 1;
public void actionPerformed(ActionEvent e) {
DatosArchivo3 datosArchivo3 = new DatosArchivo3(index, PanelCarga3.this);
datosArchivoContainer.add(datosArchivo3);
datosArchivoContainer.revalidate();
index++;
}
});
JPanel topPanel = new JPanel();
topPanel.add(btnAbrir);
datosArchivoContainer.setLayout(new BoxLayout(datosArchivoContainer, BoxLayout.LINE_AXIS));
JScrollPane scrollPane = new JScrollPane(datosArchivoContainer);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
setPreferredSize(PREF_SIZE);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
}
public void removeDatosArchivo(DatosArchivo3 datosArchivo) {
datosArchivoContainer.remove(datosArchivo);
datosArchivoContainer.revalidate();
datosArchivoContainer.repaint();
}
}
#SuppressWarnings("serial")
class DatosArchivo3 extends JPanel {
private PanelCarga3 panelCarga;
private JButton btnX = new JButton("X");
public DatosArchivo3(int index, PanelCarga3 panelCarga) {
this.panelCarga = panelCarga;
btnX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnXActionPerformed(e);
}
});
setPreferredSize(new Dimension(200, 200));
setBorder(BorderFactory.createEtchedBorder());
add(btnX);
add(new JLabel("Index: " + index));
}
private void btnXActionPerformed(ActionEvent e) {
panelCarga.removeDatosArchivo(this);
}
}

Categories

Resources