1

I want to create a simple cad-like java application.

In it there will be a Jframe in which I want to have my shapes. Those shapes will be circles and lines. Also some text will be placed. There will be up to some thousands circles, so speed is an issue. Also the shapes will have to be redrawn all the time (for example for zoom-in etc). Those shapes apart from the "standard" properties of their class I want them to have extra properties declared with new variables such as "cityname" or "speedinthisline". The shapes will have to interact on user actions (click, move ever etc).

I though for the circles I could use circular jbuttons. I found some examples on how to make such buttons, or round shaped frames. Also I found some examples on how to make clickable graphics. In vb.net OvalShape an Lineshape exist that are ready made clickable shape objects.

For ease of usage I would like to have seperate class for each shape type, in which all the extra variables could be declared.

What is the best way to focus my efforts? Go for extending components like buttons, or go for doing something out of Graphics classes? Are there any ready made classes like the ones that exist in vb.net? Any recomendations?

geo
  • 517
  • 1
  • 9
  • 28
  • 1
    please google or youtube GraphStream – Exorcismus Jan 25 '14 at 20:16
  • *"Are there any ready made classes like the ones that exist in vb.net?"* Probably what you are looking for is the [java.awt.geom package](http://docs.oracle.com/javase/7/docs/api/java/awt/geom/package-summary.html). Most of them implement [Shape](http://docs.oracle.com/javase/7/docs/api/java/awt/Shape.html) which can be painted with Graphics2D. – Radiodef Jan 25 '14 at 20:55
  • @ fady tather. From a quick look GraphStream seems to be something like I need, but I would rather not use code under LGPL. Bau I will see about that if I don't find another way to do what I need. – geo Jan 26 '14 at 06:43

2 Answers2

3

The question depends a lot on how you want to structure the program

For simplicity sake, I would go with creating a custom component, probably extending from something like JPanel and override it's paintComponent method.

This gives you a basic "paintable" component, that can easily be configured with a MouseListener...

This means you're not having to spend most of your time worrying about how to translate the mouse events.

My personal preference would be to maintain a single MouseListener, which is registered with all the elements you have on the screen and provides overall management.

The problem with this approach is zooming. It's difficult to zoom a single parent container and provide translation of the mouse events.

Lukey for your, JLayer can provide this functionality for you. This, again, saves you from having to make mouse event translations as well as trying to calculate the viewable size of the container all the time.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • If I extend Jpanel, how could I have a line? I could have a narrow panel that looks like a line, but could it be rotated, as lines are? – geo Jan 25 '14 at 20:16
  • You'd do this through the use of getPreferrdSize and paintComponent. When rotating on object. Basically you'd need calculate the resulting rectangle bounds and make the components size match it... – MadProgrammer Jan 25 '14 at 20:19
  • I don't understand what you are saying about rotating Jpanels. When manking a "line" out of a a Panel there are two ways to do it. One draw a line ON a panel (the graphics aproach), or Two, make the Jpanel BE the line. In the second case the panel has to have small hight (2-3 pixels maybe) and have to be rotated (to connect points such as (50,50)-(58,96). Can this panel be rotated to get the line efect? – geo Jan 26 '14 at 06:39
  • The `JPanel` is the surface on to which you want to paint. Don't rotate the panel, rotate the contents, but when doing this, you are going to have to calculate the rectangular bounds the would be required to show the entire line. There is an excellent answer to a question about rotating images which should give a good idea about how to do this... – MadProgrammer Jan 26 '14 at 06:48
  • To sum up, you are saying that: about circles, I should create a new class that extends Jpanel. This new object will have the shape I want. And about lines I should not do the same as with circles, but draw lines ON panels, instead of creating "line-shaped" panels. Right? – geo Jan 26 '14 at 07:04
  • Nope, everything is a `JPanel`, which is responsible for painting whatever you want. You can then apply what ever attributes you want to these classes, adding what ever features you need. It makes it easier to manage from a container point of view and lowers the amount of management you have to do... – MadProgrammer Jan 26 '14 at 07:50
  • Thanks for your answers but I am confused. Suppose I have 4 circles and the are connected with 6 lines. How many instances of panels should I have in total? – geo Jan 26 '14 at 09:09
  • Ok. In that case each line will have it's own panel that will be rectangular. Also it mast be transparent to let other lines/circles be visible. But since the actual object that can be clicked is the panel and not the line, how could I get the line that is clicked? I mean the panels would usualy overlap one over the other. When I click on a panel the topmost panel will be clicked, and not the one I want (the one with the line I want). That because the panel with the line I want maybe had been drawn under some of the other panels. – geo Jan 26 '14 at 09:14
  • Yep, use `JPanel#setOpaque` and set it to `false` for transparency. You may wish to look at `JLayeredPane` as the base container, so you can get better control over the Z-Depth... – MadProgrammer Jan 26 '14 at 09:19
  • Yes it should be transparent to view, but shouldn't panels be "transparent to clicking" too, except when clicked where the line is? – geo Jan 26 '14 at 09:23
  • That's up to you. You could do a type of line intersection checking to see if the click was on the line or not and then pass the mouse event to the next component below it, but that increases the amount of work you need to do...just saying... – MadProgrammer Jan 26 '14 at 09:50
  • I see. If I don't do what you say ("checking to see if the click was on the line or not and then pass the mouse event to the next component below it"), how could get clicked lines that are not at the topmost panel? – geo Jan 26 '14 at 10:05
0

I'm no expert on Swing, but drawing thousands of constantly morphing circular JButtons is definitely probably not going to be fast or smooth. Look into doing something with more basic Graphics packages. Here's an example of how to make a custom clickable, drawn object.

Community
  • 1
  • 1
Loktopus
  • 462
  • 2
  • 12
  • 1
    Oh, I don't know, I've animated over 4500 component based objects simultaneously, running at roughly 25fps...It all comes down to the how you manage it ;) - I actually think it's more problematic to use `JButton` just so you can get mouse events personally... – MadProgrammer Jan 25 '14 at 20:03
  • @MadProgrammer Impressive. – Loktopus Jan 25 '14 at 20:06
  • The issues necessarily the number of objects, as swing uses a passive rendering engine, meaning, it only paints what it needs when it needs. While it's a consideration, there are so many other elements to consider that aren't mentioned in the question. Just saying ;) – MadProgrammer Jan 25 '14 at 20:16