I have a Java Swing App which adds JInternalPanes on button click into a JDesktopPane. However, everytime I add a new JInternalPane to the DesktopPane, they all are overlapping and I always have to move the newest one to the side in order to see the previous one again.
Is there any way I can set the position of the newest one slightly to the right of the previous one?
I came up with this workarround but this just looks weird and there is probably a better alternative.
public void createMarket() {
this.appWindow.getDesktopPane().add(new Market(this.restClient, this.websocketClient, this.appWindow.getSymbolTextField().getText(), this.appWindow.getSelectedInterval()));
if (this.appWindow.getDesktopPane().getAllFrames().length > 1) {
JInternalFrame previousFrame = this.appWindow.getDesktopPane().getAllFrames()[this.appWindow.getDesktopPane().getAllFrames().length - 2];
this.appWindow.getDesktopPane().getAllFrames()[this.appWindow.getDesktopPane().getAllFrames().length - 1].setLocation((int)(previousFrame.getLocation().getX() + 100), (int)(previousFrame.getLocation().getY()+100));
}
}
There is no code in the Java platform that would tile or cascade JInternalFrames - you will have to write that yourself.
Here is some example of cascading internal frames:
http://www.java2s.com/Code/Java/Swing-JFC/JDesktopPaneCascadeDemo.htm
Note that the frames are placed using setBounds(). For tiling them, you'd have to check how many there are, decide about the amount of rows and columns, calculate the coordinates and call setBounds() again.
Related
I am wondering if I can achieve something like this in Vaadin 8:
The orange bar represents one progress and the green represents another one, which is subset of the orange. Basically, the green bar can be smaller or equal to the orange.
Right now, I have only
Following is the code:
AbstractLayout progressBarInformationLayout =
VaadinLayoutUtility.getInstance().generateHLayout();
progressBarInformationLayout.setStyleName("dashboard_progress_bar_info_layout");
layout.addComponent(progressBarInformationLayout);
float progressBarValue = actualIncludeTotal / (float) predictedInclude;
ProgressBar progressBar = new ProgressBar(progressBarValue);
progressBar.setId("dashboard_progress_bar");
progressBar.setWidth("230px");
progressBar.setStyleName("progress_bar");
progressBarInformationLayout.addComponent(progressBar);
Label progressLabel = new Label(df2.format(progressBarValue * 100) + "%");
progressLabel.setStyleName("progress_label");
progressBarInformationLayout.addComponent(progressLabel);
I haven't tried this, but I'd assume it's semi-easily doable by extending/overriding ProgressBar and its related classes to have two or more progress indicators.
See the handling of indicator variable in VProgressBar, calling of getWidget().setState(getState().state); in ProgressBarConnector, variable state in ProgressBarState, and the getValue and setValue handling in ProgressBar -- you are going to need to duplicate all of those. You'll also need styling for the extra indicators (see Valo styles for ProgressBar).
Given that three of the above are client-side classes, take a look at the Client-Side Development documentation if you aren't familiar with it from before, and remember to recompile your widgetset after every change.
If you ever want a version where the second bar isn't a subset of the first one but a completely different progress, and don't know upfront which task is slowest, I suppose you'll also need extra logic for determining which bar is underneath (otherwise the faster one might hide the slower one), and possibly for swapping the colors of the bars if their relative speed changes. Or you could tweak the design so that both bars are always visible.
All Swing components in my app (except labels) have tooltips that can be annoying once the user knows what's going on, so I have a Preferences menu that allows turning them off. I could name every component and set its tooltip text to "" [e.g., txtPattern.setToolTipText("");] (and 10 others), but I decided (with SO aid that started awhile back) to write code that would be more elegant (a learning experience):
private void tipsOff(Container container){
Component [] c = container.getComponents();
for (Component cc : c)
((JComponent)cc).setToolTipText("");
}
private void mniPrefTooltipsActionPerformed(java.awt.event.ActionEvent evt) {
if(! mniPrefTooltips.isSelected()){
tipsOff(gui.getContentPane());
tipsOff(gui.pnlLetters);
tipsOff(gui.mbrMenuBar);
}
else{
gui.dispose();
gui = new IO();
gui.setVisible(true);
}
}
I have a problem, which is that the tooltips are NOT turned off for the two large text areas at the bottom of the gui (highlighted in the Navigator pane). The two buttons (marked with green in Nav. pane) ARE processed correctly. These items are supposed to be processed via the first call to tipsOff, which processes gui.getContentPane()).
(I added the two lines bellow to try to rectify the problem. Nope.)
tipsOff(gui.scrOutput);
tipsOff(gui.scrScratch);
(Also tried this. Nope.)
tipsOff(gui.txaOutput);
tipsOff(gui.txaScratchwork);
How can I elegantly (i.e., assume I have many text areas, not just 2) turn off the text area tooltips?
P.S. I get the message Access of private field of another object for all but the first call to tipsOff. I don't care, owing to the nature of the task at hand.
Use ToolTipManager.sharedInstance().setEnabled( false ) to disable all tool tips in your Swing application.
Benefits compared to your approach
It works :-)
You do not clear the tooltips, so it is easy to re-enable them again. For example if you want to offer UI to your user to activate/de-activate the tooltips this approach will work. In your approach, you would have to restore all the tooltips you previously cleared, which would be difficult to do in a generic way.
I'm doing a path-finding project as part of my 4th year software engineering degree.
We're suppose to give visual representation to a bunch of multi-agent pathfinding algorithm. The simplest one is A* adapted for multiagents.
Anyway our environment is a grid map where every cell can be either blocked or used as part of an agent's path. What I want to do is use animation to give a good representation of the final movement of the agent, but animating color change in my grid.
I.E paint every step in the path for a second or so with some color to show how the agent moves.
And the other thing I want to do is to represent the way the algorithm works by painting the changes in the open list and closed list of the A* algorithm while its doing its calculation.
I'm using an adapted version of the observer design pattern to send events from my algorithm layer to my controller and GUI layer.
What I want to do in the GUI layer is every time a tile is added to the open list, I want to have that cell painted in some color and then have it fade away according to a predefined timer or maybe later add a slider to control this timer.
I looked at the code here. It seems pretty simple, the problem is that every tile animation has to be independent of the others to allow the algorithm and everything to keep running and different animations to start.
So what's the best way to achieve the results I'm looking for? Should I just open a different thread for each animation or have a pre-made thread for each cell?
Would that be an overkill for the application, since there can be up to 1000 cells and therefore close to 1000 threads performing animation.
Another issue I think I might encounter is the fact that it might happen that a cell will start its color fading animation and then will have to restart and I don't want the two animations to go at the same time (only one thread performing animation for the same cell at the same time).
I hope I was clear enough with what I'm trying to achieve, if someone has any ideas or thought it could really help me with my project.
You can find Trident animation library useful. More information at http://kenai.com/projects/trident/pages/Home
I would consider a scenario with a single animation thread only. You might e.g. try the following strategy:
standard event thread for swing events
one worker thread for your logic
only one additional for all animations
This third thread manages all animation within your gui. Therefore it maintains a list of animation actions to perform together with their timestamp. Such an action can be e.g. "set color of cell [1,2] to CF0000 # 17:01:00" in an approriate data structure. This list of actions is then filled by the worker thread with the animation actions (e.g. you may add several actions at once for a fading cell - 1) set to 100% # now; 2) set to 75% # now+10s; 3) set to 50% # now+20s ...). Make sure that this list is properly synchronized since it will be accessed from both threads.
If you keep this list sorted by timestamp it is quite easy to determine the which actions this thread has to do at any time. This thread has then a quite simple loop, e.g. something like
while(true) {
AnimationAction action = list.get(0);
if(action!=null && action.timestamp <= now()) {
action.perform(); // <= be sure that paint events occur in the edt
list.remove(0);
continue;
}
sleep(...);
}
Note that you can determine the time to sleep from the timestamp of the next action but consider that a new animation event arriving might have to interrupt this. Otherwise you can also sleep for some short amount of time.
Regarding your second question this thread might remove any actions from this list on demand for a special cell if a new action arrives. Therefore you might also maintain a secondary data structure in order to do this efficiently.
I'd use javax.swing.Timer and AlphaComposite, as demonstrated here.
Is there any default functionality for arranging JInternalFrames in Java Swing?
I would like to have the Cascade, Tile, etc... functionality within my Java Swing application like this: http://www.codeproject.com/KB/cs/mdiformstutorial.aspx
I could only find code where they did the arranging manually. Is there no support for this in Java Swing or am I a bit blind?
I've done cascade before but I did it by shifting the frames pixels to create the affect I do not know another way of doing this, I would work out how big the JDesktopPane is then get an array of you internal frames with getAllFrames(), then perform the sizing and shifting manually.
I am certain (allthough I haven't looked for at least 2 years now) that swing has no other way to perform these operations, I'm sure someone somewhere has a written a third party library to bolt onto swing apps, if not I'd write one and open source it :)
Edit,
Just thought the other way you could do tile etc, would be to write a custom layout manager that did the heavy lifting work for you something like FrameTileLayoutManager, then use that.. its just a thought.
This is not really a solution but more of a Hack. It is possible to cascade/ stack the internal frames if you can read the current width of the desktop pane before rendering the frame.
int c=desktopPane.getAllFrames().length;
Random r=new Random();
if (c<3){
RegistryDash registry = new RegistryDash();
registry.setVisible(true);
desktopPane.add(registry);
//registry.setLocation(r.nextInt(200),r.nextInt(200));
registry.setLocation(c*50,c*50);
try {
registry.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}else{
JOptionPane.showMessageDialog(this,"More than three similar windows are currently active. Close some to allow new windows.","Multiple Window Error",JOptionPane.WARNING_MESSAGE);
}
We have implemented a table-based editor with an SWT tree table. It pretty much does what we want it to, except that we can't find a way to ensure that the first few columns remain at their position when the user scrolls horizontally (so that one can identify the row being edited).
There are a number of third-party table controls in various degrees of being incomplete or abandoned, and a snippet that shows how to use two tables (which get out of sync when they're being scrolled vertically).
What's the best way to solve this?
This 'official' SWT snippet does what you want to do, at least on my machine - it does not get out of sync on vertical scroll. But the price is a second scrollbar - way ugly. To prevent this, you can add the style SWT.NO_SCROLL in the constructor of the left table.
To improve the thing you will have to add a Listener on SWT.Traverse to both Tables, which syncs them if the user navigated using keys, something like this:
leftTable.addListener(SWT.Traverse, new Listener() {
public void handleEvent( Event event ) {
rightTable.setTopIndex(leftTable.getTopIndex());
}
});
I wouldn't go with another Table implementation, since you lose the biggest advantage you have with SWT: using a native widget, which looks and feels 'right' in each OS. If you want to do that anyway, Grid from the Nebula project is much more mature than the alpha tag implies. Don't know if it can do what you want, though.
the "syncing problem" only appears on MacOs based SWT. If your target platform is windows you should have no problem with the given SWT-Snippet. There will be more listeners to register on both tables to synchronise all occuring events (collapse, expand, mouse scroll, etc.)