I've been tasked with doing refactoring to a Java Swing application we have here that's pretty crufty. My job is to clean up the code and make it more dynamic as we're going to start using it with a second project and it needs to be able to adjust appropriately. There is a small portion of one window that contains
A button
A JFormattedTextField that is used to select dates.
A 3X4 table of JLabels that display data.
The person who originally wrote this simply used a GridBagLayout JPanel and then hardcoded everything, including the table's header and row label's and left empty JLabel's in the dynamic data position. When the dynamic information is received setText is called with the text data. Part of my refactoring will cause the entire table to be dynamic in dimension as well as content so I decided to make the table a sub-panel with a GridLayout and dynamically set the contents and dimensions with this piece of code:
public void updateInfoPanel(ArrayList rows) {
System.out.println("Updating Info Panel!");
//genericInfo is the new sub panel in question.
genericInfo.removeAll();
GridLayout layout = new GridLayout();
layout.setColumns(rows.get(0).length);
layout.setRows(rows.size());
genericInfo.setLayout(layout);
for(String[] row : rows) {
for(String element : row) {
genericInfo.add(new Label(element));
}
}
}
I have verified that this is only ever getting called one time per window creation but the entire window is now incredibly sluggish. It can take >5 seconds to respond to clicks in other parts of the frame that used to respond in fractions of a second. Does anyone know what would cause this? Is there something about GridLayouts that I don't understand?
Try calling this code on the EDT.
No it appears you understand GridLayouts. The problem is elsewhere, look at other code that you might have changed, and do some profiling to determine the true source of the slowdown.
Related
I've been working on a Pokemon-themed quiz game in Java (modeled after Sporcle, if you're familiar). Pretty much everything works how I want it to, except for the layout of the different components of the program.
I've never been very good with the different layout managers, and I don't know how to get them to do what I need.
Here's what the window looks like right now:
Now, I'll play around with font sizes later, but the tables themselves look exactly how I want them to. The problem is, I want them to be under the text fields and buttons and stuff. Here's the portion of the code where I add all the components to my JPanel:
panel.add(label,FlowLayout.LEFT); //adding the "big question text"
panel.add(answerfield); //adding the JTextField
panel.add(correctAnswerTracker); //adding the "x / 151" text
for(int x = sPanes.length-1; x >=0; x--) //as you keep adding to left, it gets pushed over, so doing it backwards results in the correct order
panel.add(sPanes[x],FlowLayout.LEFT);
//each table is in a scrollPane, and all my scrollPanes are in the array sPanes, so I'm looping through that to add the tables
panel.add(startStopButton); //button that says "Start"
panel.add(exit); //button that says "Exit
panel.add(timer); //the timer
As you can see, the statements to add the text field, and correct answer tracker are all written before the add statement for the tables, and yet the tables are at the top. Additionally, there's the issue of my tables in that loop being added in the backwards order, so I had to reverse the direction of the loop iterations to get the tables to appear in the correct order. I've tried using stuff like setLocation and setBounds to get my components more where I want them, but nothing happened. Also, everything just appears in a row below the tables (and I know that's what FlowLayout does), but how would I go about customizing exactly where things appear?
Wrap a panel with BorderLayout around ones with FlowLayout. Put all the content that should be above the tables in a panel and add it with BorderLayout.NORTH. Put all the content that should be below the tables in another panel and add it with BorderLayout.SOUTH. Then put the tables in their own panel just as your are now, and add it with BorderLayout.CENTER.
Either use a LayoutManager or setLayout(null). In the latter case, you can move your components around by calling setBounds on them. I've been doing that lately too (not using a LayoutManager), it's quite liberating.
I am using LibGDX and Scene2D to create a simple menu for my game.
Here is a simple example that works for me:
table.add(gameLogo).row();
table.add(button1).row();
table.add(button2).row();
table.add(button3).row();
I didn't include the irrelevant code(including the table into the stage for example).
If I don't include .row() to each object that I add to the table, then the menu isn't aligning to the center, which is very odd, for example:
table.add(gameLogo).row();
table.add(button1);
table.add(button2).row();
table.add(button3);
Why is the menu behaving like that? should I use more tables or add some HorizontalGroups perhaps?
If you need any additional information, or images I can provide, although it does the same for even the simplest menu implemention possible with LibGDX and Scene2d.
This is a colspan problem.
Looking at your code, this is what you are currently doing :
I assume that you would like to display your menu like that :
In order to do that, as you can see, you need to set the colspan size of your gamelogo to 2, so that it will take as much size as 2 regular cells.
So, to achieve this result, your code should be :
table.add(gameLogo).colspan(2).center().row();
table.add(button1);
table.add(button2).row();
table.add(button3);
The align(Align.center) or center() methods will not work alone, since these methods are only used to align the widget inside it's own cell.
If you experience more problems with libgdx ui table, remember that you can enable a debug renderer to display the cells border :
table.setDebug(true);
everyone.
I'm currently working on a project which is written in Java. As one of my features I want the application to display List of workout plans that are saved in the databases. Furthermore, I want the user to be able to click on particular instance of the workout Plan so that new JFrame is opened with further details which will be populated from the database.
You can see what I mean in the picture below, this is how I want my list to look like.
For this application I'm using Swing components to model my GUI. Its very important for me that those items within a list will act as a button so that you can open up new JFrame, but at the same time the content must be populated from database. Also when a new Workout Plan is added to the database the list must be updated and the item that will be added to that list has to be of the same format.
My question is whether it's possible to design that kind of list using Swing components, and if it is how would you do it.
Any suggestions or help will be appreciated.
I'm not that familiar with swing but, I think you can set your panel into a grid layout. Then divide the grid layout so that there are, for example, 10 rows and 1 column. Afterwards, fill the grid layout with JButton's. Whenever a button is pressed, it will open up a JFrame.
I feel like there's a better way to do this though.
I have created general bill maker application on swing in which i've to print receipts as the output.
Basically i am not able to understand how can show the list of items on the panel so that it is able to print?
I am using PrintUtilities.java to print
the receipt panel.
What i am trying is to use a JTable for listing item details but if number of items is more than scrollpane viewport hieght than the rest of extra items are not shown and thus unable to print.
What can be the other way if i do not use JTable?
Or a solution with JTable itself.
What i want is to extend my whole dialog vertically if no. of items exceeded rather than using autoscrolls in JTable's scrollpane.
I hope i am clear to my question.
Here is the image of what i am trying.
I wouldn't use Swing components as printed components. Instead I'd build a PDF of the receipt and let the user print that. Scrolling is just going to be a problem with printing actual swing components that isn't easy to handle. This is a great PDF library:
http://pdfbox.apache.org/
I have a list of entities where each entity render into widget based on JPanel. Widgets have dynamic behaviour - once placed on panel it can be changed by underlying entity. This happens automaticaly. Moreover some widgets can be resized by different actions, on button click for example.
The question is how to organise them into something like JList but without rubber stamp technics. In other words I wanna JList where each item rendered with cellrenderer stay "alive".
Right now I have implemented quick-and-dirty component based on JPanel with vertical BoxLayout, it uses JList's renderer component and it's model... but my implementation is too dirty...
Um.. yeah, using JTable is not suitable too.
Do you have some ideas?
If you don't want rubber stamping to take place then you'll have to create your own JList implementation that uses actual components.
You could try and work around the rubber stamping effect by caching each component for each row in your renderer and bind values into it and return that instance when JList asks the renderer for it. This is pretty risky because if you have 20 rows being displayed you'll have to cache 20 instances in your renderer, and only when the row isn't visible can you reuse one. That would mean if you had 5 unique configurations (A,B,C,D,E) of components you might have 10 of type A, 5 of type B, 2 of type C, and 3 of type D, and 0 of type E being displayed. However, you can't simply reuse one of those components without knowing if its being displayed or not. So you'd have to take into account if the row is being displayed and if it's the right type for the row you are rendering. And you'll have to clean up after the row is hidden.
Another option is make a single component for the row that encapsulates all X variations you have and put those on a CardLayout. Then you can simply cache one per row being displayed, and simply swap the card being displayed upon rendering that row. I think that might be the simplest option for you.
The harder part is going to be routing events click mouse clicks, keyboard events, etc to those active components to have them respond like normal components. Re-rendering the buttons when the user clicks them, and so forth is going to be challenging. Not impossible, but tedious.
Finally, variable row height JList is a pain. Especially in your calculations to figure out if a row is displayed or not because you can't simply do easy math like: int rowHeight = jlist.getHeight / model.size(). It doesn't work. You have to calculate each row's height and them up to figure out if a row is visible or not.
Doing what you're talking about is a lot of work, and very tricky coding to work around some of the assumptions of JList to make it work. In the end you might find it easier just to implement your own List control that makes different design decisions. Either way its going to require you are good at Swing to get it to work.
Ok. I don't find any implementation of such component. Let it be first one.
https://github.com/wertlex/JActiveList
P.S. I don't think this is proper way implementation... but it works.
use JList and ActionListener XD