Win a copy of Succeeding with AI this week in the Artificial Intelligence and Machine Learning forum!

Austin Henggi

Greenhorn
+ Follow
since Jul 08, 2005
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Austin Henggi

I simply want to draw text inside of a rectangle. Easy. Harder: I would like the text to be as readable (translate: big) as possible with the constraint that it must be contained in the rectangle. I know about getAscent() and getDescent() and how to iterate through font types and sizes to find something that fits. But is there a more efficient / existing code for finding best font size to render a text string in a rectangle so that it is as readable as possible?
9 years ago

pete stein wrote:I've never seen a background thread called from within the paintComponent method before, and while I suppose that there may be rare times when this may be done (but I haven't a clue as to one) I don't feel that this is one of them. Why not create the BufferedImage in a background thread not called by paintComponent, and then when done, call repaint() on the drawing JPanel, and in the paintComponent method if the BufferedImage isn't null, paint it by calling g.drawImage(myBufferedImage,.....)?

Oh, by the way, thanks for the link to the cross-post; it's much appreciated.



From the code posted above, JFreeChart does render the chart to a BufferedImage first and then paints the buffered image to the canvas / JPanel. I think they do this because it allows for better abstraction among the renders, but if only one chart is rendered, it would slow things down a bit compared to directly rendering to the screen. One question I have though is how would multiple repaint events be handled? For example, when I resize a window, the Swing Event Dispatcher is actually firing off several repaint events, I'm guessing one per every pixel of frame size change. And if I did this with background thread, how I avoid spawning off one new event per pixel change? Maybe I'm not understanding or forgot some details about how swing works, but it seems that there needs to be some sort of filter for cutting out redundant repaint calls. Second, changes to the chart data set or other chart parameter (zooming, mouse cursor, etc) cause a call to paintComponent where a Graphics object is passed in. So if I were to also call repaint() when the rendering of the BufferedImage is finished, how would I tell whether the call to paintComponent means: 1) something changed, redraw the bufferedImage or 2) buffered image rendering done, paint bufferedImage? In case 1) once the BufferedImage is rendered, another call to paintComponent is made so we would enter an infinite loop. I don't have much experience with Swing Threading, but I think your idea is correct. I just don't see how to implement it.

Update: I was able to implement your approach because JFreeChart has a refreshbuffer flag which indicates whether the bufferedImage needs to be recomputed. So I simply made another function called refreshBuffer where I do just that if the buffer needs rendering. I do the rendering in a separate thread. There's a few problems. First although it draws the charts, there's some glitch at the beginning where all charts are the same for a second or two. Second, I still seem stuck using only one thread. CPU pegs at 25% (on a 4 core machine). I put in some getCurrentSystemTime and I see that each thread takes much longer to execute. So it seems like the threads are running in parallel, but only on one CPU core. I think some of these problems might relate to what I mentioned above in my previous post. If a chart receives multiple update calls, it will simply spawn a new thread for each call. Instead, what should happen is that if there's a more recent update call while the bufferedimage is being rendered, that rendering should stop (be interrupted) and start-over. This is because something has changed since the rendering started and therefore, rendering must be restarted. I suspect that Swing event handler has a way of dealing with this situation. In order to background render, I think there's something else that I'm still missing. Here's the code, all I really did was create a new function refreshBuffer which copies the bufferedImage rendering part of JFreeChart's original paintComponent method.


9 years ago
JFreeChart is a popular Java library drawing charts. In my application, I wish to render around 10 charts and I'd like to render them in parallel. JFreeChart renders its charts using BufferedImages. The code for paintComponent is here:



I already tried to thread this function via this code:



But this doesn't work. It only paints a gray screen which resizes correctly, but no buffered image. What's the best way to multithread the above paintComponent? (Note, I started this topic here:

http://ubuntuforums.org/showthread.php?p=9657545#post9657545 and I'm not a fan of crossposting. I just realized that this topic is a bit more advanced than most swing questions and thought the community here would be better able to answer my question.
9 years ago
Actually, I think I it would have been better to describe what I am looking as how to show a different view on the fly. In other words, I would have something like a BorderLayout view with a main panel in the center surrounded by other panels in the BorderLayout west and east. Then I would change views by stripping away the other panels on the west and east, but eventually I would want to go back to the first view, or maybe a different view which does not contain the main panel at all. However, all this would happen in one frame or panel, despite the title of my post, there is no window. Sorry, my title is misleading.
12 years ago
I am not sure how to describe this, but basically, I want a program that will have a single window, but multiple "views". So say that there is one option on the toolbar that shows a JPanel with some stuff on it, surrounded by three other JPanels with other options to the left, bottom, and right of the main JPanel. Then the user can click on another option under the JMenu bar and get a different view, this time just showing the main panel, although enlarged slightly. And there will probably be at least one other view as well. How would I do this?

One approach that I thought of would be to create one JFrame and just add and remove panels from it as needed. However, it would be nice also to just setup the multiple views once and then switch the display between them as needed vs. adding and removing components from a single JFrame. Question is: what is the best way to implement these multiple views (keep in mind that they should all share the same window), it is a single-window program.
12 years ago
I have a JTree which is inside a JScrollPane which is inside a JPanel that I want to put inside of a JFrame. The tree appears in the center of my frame as it should before I apply my layout. I create a springlayout and then set the layout to my FRAME. I then set up springs to add constraints on where I want my panel to appear, but no matter what I do, the panel always appears in the top right-hand corner of my screen. I am not sure why. My code is below, any suggestions?

public SimpleTree(JFrame frame, SpringLayout layout)
{
DefaultMutableTreeNode top =
new DefaultMutableTreeNode("The World");
CreateNodes(top);
JTree tree = new JTree(top);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
JScrollPane treeView = new JScrollPane(tree);
treeView.setHorizontalScrollBarPolicy(
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
treeView.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
treeView.setBounds(100,100, 50,50);
JPanel treePanel = new JPanel();
treePanel.add(treeView);
frame.setLayout(layout);
treePanel.setBounds(100,100,50,50);
frame.getContentPane().add(treePanel);
Spring s = Spring.constant(200,300,800);
layout.putConstraint(SpringLayout.EAST, frame, s, SpringLayout.EAST, treePanel);
layout.putConstraint(SpringLayout.WEST, frame, s, SpringLayout.WEST, treePanel);
layout.putConstraint(SpringLayout.NORTH, frame, s, SpringLayout.NORTH, treePanel);
layout.putConstraint(SpringLayout.SOUTH, frame, s, SpringLayout.SOUTH, treePanel);
}
14 years ago
Thanks Pat for the response! I will check the program out.
14 years ago
Does anyone know of a Java chat room where people can go and ask questions?
14 years ago
Austin,
Place the JScrollPane in a JPanel. Then add the Panel to the frame.
14 years ago
As you may be able to tell from the headline, I am a bit of a newbie at this. What I am trying to to is create a very basic GUI that contains a directory JTree and some other components. I have successfully build the tree, but I am trying to add it to a specific position in my frame. I added the tree to a JScrollPane so that the user can scroll around the tree. So I assume that by setting the parameters of JScrollPane through the inherited setBounds() command of the Component class, I can control where my JScrollPane and hence my tree appears within the frame. But for some reason my code compiles, but the directory tree appears in the top left hand corner of the screen. My relevant code is below. Also, if I want to create a simple button and specify its position in the frame along with the physical dimensions of the button (height, width), do I simply call the setBounds command to position the button within my frame? It is necessary to add the button to a container or does the button class provide its own container?

class SimpleTree extends JFrame
{
public SimpleTree(JFrame frame)
{
DefaultMutableTreeNode top =
new DefaultMutableTreeNode("The World");
CreateNodes(top); //CreateNodes adds nodes to "top", the root of my tree.
JTree tree = new JTree(top);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
JScrollPane treeView = new JScrollPane(tree);
treeView.setHorizontalScrollBarPolicy(
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
treeView.setVerticalScrollBarPolicy(
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
treeView.setBounds(100,100, 50,50);
JViewport treeport = treeView.getViewport();
//treeport.add(tree);
//treeView.setViewport(treeport);
//Dimension treesize = new Dimension(treewidth, treeheight);
//treeport.setViewSize(treesize);
//Point treeposition = new Point(treex, treey);
//treeport.setViewPosition(treeposition);
frame.getContentPane().add(treeView);
treeport.setBounds(100,100, 50,50);
}
14 years ago