I need to create some tabbedpane called "menu" and in each of them I need to put a Jlist (product) with some other data extracted from a mysql db. I created this method but unfortunately it shows only the last jlist, the others menu tabbedpane are empty. Why? Thanks.
for (int i = 0; i < menuLista.size(); i++) {
int menuId = menuLista.get(i).getMenuId();
jProductList = new JList(modelProductList);
prodottiLista.clear();
modelProductList.clear();
prodottiLista = DBManager.fillProductList(menuId);
for (int b = 0; b < prodottiLista.size(); b++) {
modelProductList.addElement((Product) prodottiLista.get(b));
}
jProductList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jProductList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
jProductListValueChanged(evt);
}
});
JPanel pL = new JPanel();
pL.add(jScrollPane3);
// panelList.add(pL);
jTabbedPane1.addTab(menuLista.get(i).getMenuName(), pL);
jScrollPane3.setViewportView(jProductList);
}
I've modified the code like this:
for (int i = 0; i < menuLista.size(); i++) {
int menuId = menuLista.get(i).getMenuId();
modelProductList.clear(); // ricarico la lista dei prodotti.
prodottiLista = DBManager.fillProductList(menuId);
for (int b = 0; b < prodottiLista.size(); b++) {
modelProductList.addElement((Product) prodottiLista.get(b));
}
System.out.println(modelProductList);
JScrollPane scrollPane = new JScrollPane(jProductList);
jTabbedPane1.addTab(menuLista.get(i).getMenuName(), scrollPane);
jProductList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jProductList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
jProductListValueChanged(evt);
}
});
}
But It still doesn't work as I expected.
EDITED AGAIN:
I noticed that if I put this line:
System.out.println(modelProductList);
after that block of code, it prints exactly only the last products.
So, it's not a problem of visualization. Any suggestion?
jTabbedPane1.addTab(menuLista.get(i).getMenuName(), pL);
jScrollPane3.setViewportView(jProductList);
You add the last JList created to the viewport of the scroll pane. A viewport can only contain a single component.
I would guess you should be adding the tabbed pane to the viewport of the scroll pane. The tabbed pane should be added to the viewport outside of the loop, after all the tabs have been created.
Edit:
Sorry, I misread your code, I see you are adding the list to the scrollpane to a panel to the tabbed pane, so my suggestion is wrong.
However, I was close (I think?). I believe the problem is now with this line:
pL.add(jScrollPane3);
You only have a single instance of the scroll pane, so it can only be displayed on the last tab.
You need to create a new scroll pane for each tab. I would use code like the following:
JScrollPane scrollPane = new JScrollPane( jProductList );
jTabbedPane1.addTab(menuLista.get(i).getMenuName(), scrollPane);
There is no need to add the scroll pane to the panel first. Now the scrollpane will resize as the size of the tabbed pane resizes.
Also, as a side not you should not be using instance variables in your for loop. Instead you should just be using local variables, since these variables will only exist to help you create the GUI objects you add to the tabbed pane.
For example, jProductList, prodottiLista, modelProductList, should all be local variables and you need to create a new instance of each class. You can't just clear() the contents from the model, because each JList will not have a reference to the same model, so again the data that you add to the last tab will be displayed on all tabs.
Ok, I've resolved. This is the working code:
for (int i = 0; i < menuLista.size(); i++) {
int menuId = menuLista.get(i).getMenuId();
DefaultListModel modelProductList = new DefaultListModel();
JList jProductList = new JList(modelProductList);
prodottiLista = DBManager.fillProductList(menuId);
for (int b = 0; b < prodottiLista.size(); b++) {
modelProductList.addElement((Product) prodottiLista.get(b));
}
JScrollPane scrollPane = new JScrollPane(jProductList);
jTabbedPane1.addTab(menuLista.get(i).getMenuName(), scrollPane);
jProductList.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
jProductListValueChanged(evt);
}
});
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jProductList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
Related
Ok, so I'm trying to create two separate JScrollPanes that takes two lists; One list of users and one list of books and simply presents them. The problem is that right now, I have 19 items in my "bookData"-array and 15 in my "userData"-array, but both my JScrollPanes are as empty as my wallet.
When checking my DefaultListModels with getSize(), I see that they too are 15 and 19 in size. I feel like I'm missing something crucial here. The million dollar question is what?
!! - EDIT:
Just noticed the ODDEST behaviour!
My lists aren't empty as such - This is how the window looks on start;
http://i60.tinypic.com/2nr0kyu.png
BUT - and here's the twist! As soon as I change size on the window by dragging the corners - MY LISTS APPEAR! Thus, the error is not in the lists, but in the graphics, methinks. :3
http://i61.tinypic.com/2ah7ac3.png
This is how my method looks;
public void newLoan(){
StringBuilder sb = new StringBuilder();
StringBuilder string = new StringBuilder();
JLabel userLabel;
JLabel bookLabel;
JButton btnRegister;
// Build a string of all users, separated with a "–"
for (int i = 1; i < Processes.userList.size()+1; i++) {
sb.append(Processes.userList.get(i).getFirstname()+" "+Processes.
userList.get(i).getSurname()+", "+Processes.userList.
get(i).getPersonalID()+"–");
System.out.println(Processes.userList.get(i).getFirstname()+" "+Processes.
userList.get(i).getSurname()+", "+Processes.userList.
get(i).getPersonalID());
}
// Build a string of all books, separated with a "–"
for (int i = 1; i < Processes.bookList.size()+1; i++) {
if (Processes.bookList.get(i).getAvailable()-
Processes.bookList.get(i).getOnLoan()!=0) {
string.append(Processes.bookList.get(i).getAvailable()-
Processes.bookList.get(i).getOnLoan()+" available - "+
Processes.bookList.get(i).getTitle()+" by "+Processes.
bookList.get(i).getAuthor_firstname()+" "+Processes.
bookList.get(i).getAuthor_surname()+" ("+Processes.
bookList.get(i).getIsbn()+")–");
System.out.println(Processes.bookList.get(i).getAvailable()-
Processes.bookList.get(i).getOnLoan()+" available - "+
Processes.bookList.get(i).getTitle()+" by "+Processes.
bookList.get(i).getAuthor_firstname()+" "+Processes.
bookList.get(i).getAuthor_surname()+" ("+Processes.
bookList.get(i).getIsbn());
}
}
// split sb at the "–"'s and fill an array.
String[] userData = sb.toString().split("–");
System.out.println(userData.length);
// split string at the "–"'s and fill an array.
String[] bookData = string.toString().split("–");
System.out.println(bookData.length);
/* Defining sizes and locations and initializing all variables. Also
* defining text on buttons and labels.*/
DefaultListModel userModel = new DefaultListModel();
for (int i = 0; i < userData.length; i++) {
userModel.addElement(userData[i]);
}
System.out.println(userModel.getSize());
final JList userJList = new JList();
userJList.setModel(userModel);
JScrollPane userList = new JScrollPane(); //f*cking JScrollPane! Work!
userList.setViewportView(userJList);
DefaultListModel bookModel = new DefaultListModel();
for (int i = 0; i < bookData.length; i++) {
bookModel.addElement(bookData[i]);
}
System.out.println(bookModel.getSize());
final JList bookJList = new JList();
bookJList.setModel(bookModel);
JScrollPane bookList = new JScrollPane();
bookList.setViewportView(bookJList);
userLabel = new JLabel("Select user to register loan onto:");
userLabel.setSize(250,20);
userLabel.setLocation(20, 50);
userList.setSize(150, 200);
userList.setLocation(70, 80);
bookList.setSize(150, 200);
bookList.setLocation(400, 80);
btnRegister = new JButton("Register loan");
btnRegister.setSize(150,50);
btnRegister.setLocation(235, 300);
// Adding functionality... Later
// Adding the different components to the panel "newLoan".
newLoan.add(userLabel);
newLoan.add(userList);
newLoan.add(bookList);
newLoan.add(btnRegister);
}
My first thought was to simply use my String arrays and present them in the JScrollPanes, as such;
final JList userJList = new JList(userData);
JScrollPane userList = new JScrollPane();
userList.setViewportView(userJList);
But that didn't work, obviously.
The solution was extremely complex. Added private DefaultListmodel's outside the method for each of the lists and added everything as elements to those models. And last, but not least I repainted the JPanel using;
newLoan.repaint();
private void buttonAddJobActionPerformed(java.awt.event.ActionEvent evt) {
try {
retrieveID();
String sqlStm = "INSERT INTO Job (employerID,title,description,type,salary,benefits,vacancies,closing,requirement,placement,applyTo,status,posted,location) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
pst = conn.prepareStatement(sqlStm);
pst.setInt(1,id);
pst.setString(2,txtTitle.getText());
pst.setString(3,areaDescription.getText());
pst.setString(4,comboType.getSelectedItem().toString());
pst.setString(5,txtSalary.getText());
pst.setString(6,areaBenefits.getText());
pst.setString(7,txtVac.getText());
Date close;
close = txtDate.getDate();
pst.setString(8,sdf.format(close));
pst.setString(9,areaReq.getText());
pst.setString(10,comboPlace.getSelectedItem().toString());
pst.setString(11,txtWeb.getText());
pst.setString(12,comboStatus.getSelectedItem().toString());
Date now = new Date();
pst.setString(13,sdf.format(now));
pst.setString(14,txtLoc.getText());
pst.executeUpdate();
JOptionPane.showMessageDialog(null,"You have successfully added a job");
//empty all JTextfields
//switch to another
I am trying to empty the set of JTextFields in the JPanel, but instead of emptying them one by one, can I just refresh the panel? if so, how do you do this. i tried repaint(), revalidate() these dont work. perhaps I am wrong here.
I would also like to switch the JTabbedPane to another Pane, but this doesnt work when I try with this...
JTabbedPane sourceTabbedPane = (JTabbedPane) evt.getSource();
sourceTabbedPane.setSelectedIndex(0);
can someone show an example code how to do this.
You could loop through all components that are contained in the panel, and if they are text components, clear their value. The code would be something like this:
private void clearTextFields(Container container)
{
int count = container.getComponentCount();
for (int i = 0; i < count; i++)
{
Component component = container.getComponent(i);
if (component instanceof Container) {
clearTextFields((Container) component);
}
else if (component instanceof JTextComponent) {
((JTextComponent) component).setText("");
}
}
}
This method works recursively and takes care of the case when your panel contains another panel which contains the text fields.
Keep all your JTextFields in a container, and iterate over that container to empty them.
So, somewhere:
ArrayList<JTextField> textFields = new ArrayList<JTextField>();
After all fields are actually created (with JTextField txtTitle = new JTextField() or similar):
textFields.add(txtTitle);
textFields.add(areaDescription);
// ... add all others here
And finally, when you need to clear them all:
for (JTextField tf : textFields) {
tf.setText("");
}
Hi here are my codes for my table settings:
String [] column = {"MacAddress","PcName","OperatingSystem","IpAddress","Port","Status"};
model = new DefaultTableModel(0,column.length);
model.setColumnIdentifiers(column);
mainTable = new JTable(model);
mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
for(int i=0;i<=column.length-1;i++){
mainTable.getColumnModel().getColumn(i).setPreferredWidth(300);
}
pane = new JScrollPane(mainTable);
pnlTabel = new JPanel();
pnlTabel.setBorder(BorderFactory.createTitledBorder(""));
pnlTabel.setPreferredSize(new Dimension(dim.width*70/100, dim.height*60/100));
pnlTabel.add(pane);
addMainPanel(pnlTabel);
Here is my addMainPanel() function:
public void addMainPanel(Component pnl){
mainPanel.add(pnl);
mainPanel.revalidate();
}
And here is my code for my mainPanel:
mainPanel = new JPanel();
mainPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
add(mainPanel,"Center");
and I'm using border layout for my frame:
setLayout(new BorderLayout(0,0));
My problem is that, even i use this set of code to set my JTable to fit but it seems to fail all the this, this code:
mainTable.setAutoResizeMode(JTa![enter image description here][1]ble.AUTO_RESIZE_OFF);
for(int i=0;i<=column.length-1;i++){
mainTable.getColumnModel().getColumn(i).setPreferredWidth(300);
}
When is use that code, my jtable does not resize but only add on a horizontal scroll bar at the bottom.
No offense meant but .. your code and consequently your question is a mess ;-) Plus you don't explain what exactly you want to achieve.
Trying to detangle, taking the nested layouts/resizing characteristics (as seen in the snippets, might not be complete):
frame // BorderLayout
mainPanel // FlowLayout
pnlTabel // FlowLayout, hard-coded prefSize
pane // scrollPane
mainTable // auto-resize-off
Aside: intentionally kept untelling names to demonstrate how mixing naming schemes tend to contribute to overall confusion :-) Doesn't really matter whether you decide for pre or postFixing some type-related marker, but if you do be consistent.
In that hierarchy, there are two levels of FlowLayout which basically will layout their children at their respective prefs and adjusting their own pref accordingly, lest the pref were hard-coded on the level of the pnlTable: however the table's pref will be changed (by changing the column prefs) it cannot bubble further up because ... hard-coding the pref leads not calculating its size (neither by layoutManager and nor uiDelegate, both never get a chance to do it)
Another issue - the more interesting one :-) - is that the JScrollPane is somewhat special in
calculating its own prefSize from its view's pref/scrollablePrefViewportSize depending on whether or not the view implements Scrollable (JTable does so, though in a crappy way)
being a validationRoot: invalidating the view (or any children) doesn't bubble further up the hierarchy
Assuming that you want the table's scrollPane to grow if the prefWidts of the columns change, there are two thingies to tweak:
implement table's getPreferredScrollableWidth to return a value calculated based on the prefWidth of the columns
revalidate a container higher up in the hierarchy
Some code to play with:
final JTable table = new JTable(50, 10) {
// properties to base a reasonable prefScrollable size
int visibleColumns = 3;
int visibleRows = 10;
// hard-coded default in super
Dimension dummySuper = new Dimension(450, 400);
#Override
public Dimension getPreferredScrollableViewportSize() {
Dimension dim = super.getPreferredScrollableViewportSize();
if (!dummySuper.equals(dim)) return dim;
dim = new Dimension();
for (int column = 0; column < Math.min(visibleColumns, getColumnCount()); column++) {
dim.width += getColumnModel().getColumn(column).getPreferredWidth();
}
dim.height = visibleRows * getRowHeight();
return dim;
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
for (int i = 0; i < table.getRowCount(); i++) {
table.setValueAt("row: " + i, i, 0);
}
JComponent tablePanel = new JPanel();
tablePanel.add(new JScrollPane(table));
Action sizeColumns = new AbstractAction("size columns") {
int prefWidth = 75;
#Override
public void actionPerformed(ActionEvent e) {
int newWidth = prefWidth + 15;
for (int i = 0; i < table.getColumnCount(); i++) {
if (table.getColumnModel().getColumn(i).getPreferredWidth() == prefWidth)
table.getColumnModel().getColumn(i).setPreferredWidth(newWidth);
}
prefWidth = newWidth;
// revalidate "higher up" than the table itself
frame.revalidate();
}
};
frame.add(new JButton(sizeColumns), BorderLayout.SOUTH);
If you want a JTable to fill the available space, you should put it inside a JPanel which has a BorderLayout layout manager. Also don't forget about the JScrollPane which ensures that if the table doesn't fit into the view (e.g. too many rows), scrollbars will appear:
JFrame frame = new JFrame();
// set up frame
JTable table = new JTable();
// Set up table, add data
// Frame has a content pane with BorderLayout by default
frame.getContentPane().add( new JScrollPane( table ), BorderLayout.CENTER );
If you have other content you wish to display besides the table, you can add those to the NORTH, SOUTH, EAST, WEST parts of the content panel (which can be wrapped into other panels if more components are to be placed there).
I've got MyJPanel(extends JPanel). Each MyJPanel object has method GetID(). When I create it I set ID with constructor(but also there is method SetID()), set size and then create Jscrollpane and add it to JInternalFrame. All frames are in ArrayList<JInternalFrame> arr.
JInternalFrame frame = new JInternalFrame("Inner frame",true,true,true,true);
final MyJPanel panel = new MyJPanel(f.getAbsolutePath(),count);
panel.setSize(panel.getWidth()/6,panel.getHeight()/6);
JScrollPane pane = new JScrollPane(panel);
pane.setPreferredSize(new Dimension(theDesktop.getWidth() / 2, theDesktop.getHeight() / 2));
frame.getContentPane().add(pane, BorderLayout.CENTER);
To delete frame I add add FrameListener and method internalFrameClosing method
public void internalFrameClosing(InternalFrameEvent e) {
int index = panel.GetID();//get index of panel окна
if (index == arr.size())
arr.remove(index);//remove last element
else{
//reset all indexes of JInternalFrames' MyJPanel
}
}
But I don't know how to reset values for MyJPanels in array of JInternalFrames when one of the frames was deleted because
1)MyJPanel is in JScrollPane. method SetID
2)JScrollPane is in JInternalFrame
3)JInternalFrame is in the array. No method SetID() in arr.get(i).
A simple solution is to have a Map such as a HashMap -- HashMap<JInternalFrame, MyJPanel> -- that would allow you to easily associated the MyJPanel with the internal frame that holds it. Then when you iterate through the JInternalFrames, it would be easy to retrieve the MyJPanels that each hold.
Something like:
public void internalFrameClosing(InternalFrameEvent e) {
int index = panel.GetID();
arr.remove(index);
if (index < arr.size()) {
for (int i = 0; i < arr.size(); i++) {
JInternalFrame internalFrame = arr.get(i);
MyJPanel myPanel = framePanelMap.get(internalFrame);
myPanel.setID(i);
}
}
}
Incidentally, you do know that this if (index == arr.size()) will never be true, since if your index is an index into the list, then index will hold a value between 0 and arr.size() - 1 and will never == arr.size().
Though this is somewhat of a kludge. In my mind a better solution is perhaps to do a code re-design and have the model logic of your code separate from the view portion of the code so that you would have an ArrayList of models rather than JInternalFrames.
This way, if later you decide that you don't really want to use JInternalFrames to display this information, you wouldn't have to change the basic logical structure of the model.
I am making a monopoly game in Java and for some reason I cant seem to get this JFrame popup to refresh. When I click the button, the popup will appear, but when I close it and click it again later on it the game, it continues to show the features of the 1st JFrame. I assume that a totally new JFrame is created every time you click the button, but I cant seem to refresh the content. How do I fix this?
final static JButton tradeButton = new JButton("Click to Trade Property");
tradeButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0){
final JPanel tradePanelcombo = new JPanel();
for(int x = 1; x< Player.Props.size(); x++)
{
if(x != Player.CurrentPlayer)
{
ArrayList<Property> props = Player.Props.get(x);
ArrayList<String> propnames = new ArrayList<String>();
for(Property prop : props)
{
propnames.add(prop.getName());
}
String[] strings = new String[propnames.size()];
for (int y = 0; y<propnames.size(); y++)
{
strings[y] = propnames.get(y);
}
JLabel confirmLabel = new JLabel("Player :" + x);
JComboBox petList = new JComboBox(strings);
petList.setPreferredSize(new Dimension(100, 150));
tradeFrame.add(confirmLabel);
tradePanelcombo.add(petList);
}
}
tradeFrame.add(tradePanelcombo, BorderLayout.PAGE_END);
tradeFrame.setPreferredSize(new Dimension(500,500));
tradeFrame.setResizable(true);
tradeFrame.pack();
tradeFrame.setVisible(true);
}
});
It appears to me that a new frame and components are created every time.
So, if the frame doesn't update, then I guess it would be because your Properties are not updated so the data added to the components doesn't change.
Edit:
You need to create a new JFrame every time, or you need to remove all the old components from the frame before adding the new components.
When you add a component to a BorderLayout, the previous component doesn't get removed. So you actually have two components in the container. When Swing paints components it actually paints the components in the reverse order that they where added to the container (this is how Z-Ordering works).
If you remove the setResizable() method, and then resize the frame I believe you should see the new components start to show given that they should increase in size as the frame size increases.