Java SWT Draw a Plan - java

I'm programming my first java App, I wanna create a GUI, which allow to draw different Plan. As close as possible to this representation :
My implementation is based on SWT.
For drawing Nodes and Edges, I used addPaintListener() method from the class Canvas.
But i have following problem, the method paintControl() is called infinitely times, redrawing every time.
I ask myself if there is a way to avoid it, or maybe a better way to draw a plan in Java.
Can someone of you suggest me a best way to draw diagram and edge in Java
Canvas canvas = new Canvas(composite, SWT.ALL);
canvas.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
Rectangle rect=new Rectangle(0, 0, 60, 30);
e.gc.drawRectangle(rect);
}
});

i'm searching for a best implementation for my Gui-application.i have a problem in drawing edges

Related

Drawing dynamic primitives in Java SWT

I have a C++/Qt background and am now learning Java and SWT GUI programming. I need to draw some primitive shapes (circles, rectangles, etc.) on an image. The shapes need to move on the image (ie. change its position in relation to the background, imagine a real-time updating map). In Qt this could be easily done by using QGraphicsScene and QGraphicsItems but how to achieve this in SWT? I have tried to use Composite with Label which is close to what I need but I haven't found a way to add primitive shapes to the Composite.
The Canvas control is specifically for drawing on. Basic drawing operations are in the GC class.
Canvas drawWidget = new Canvas(composite, SWT.NONE);
drawWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
drawWidget.addPaintListener(new PaintListener() {
#Override
public void paintControl(final PaintEvent e) {
Rectangle r = drawWidget.getClientArea();
e.gc.drawOval(0, 0, r.width - 1, r.height - 1);
}
});
Call the Canvas redraw method to request that the control be redrawn. This will call the paint listener again.
Other Eclipse packages such as Eclipse GEF provide much more sophisticated drawing APIs.

Drawing to canvas

so i am dabbling in making a game and i am a fairly messy worker and then i go back and tidy it up. So please ignore any stupid naming conventions or methods or anything. As I go back later and tidy up.
So basically I am trying to make a main menu, i just want to draw something to the screen and have it stay there. I am writing the graphics to a image ATM and displaying the image as i tried just drawing to the canvas and it just flickered up onto the screen and then it went blank. I changed it to a runnable so i could put in sleep() to try and error hunt. I've removed all my error hunting code now. It turns out when i have a sleep() before or after the image is put on the screen for longer than 50ms the rectangle stays on screen and doesn't flicker away like 1ms after it was drawn.
I'm not sure what's going on. I am probably not that clear and I apologies.
import java.awt.Canvas;
import java.awt.Graphics;
import javax.swing.JFrame;
public class test extends Thread{
public static void main(String[] args){
test t = new test();
t.start();
}
#Override
public void run() {
JFrame f = new JFrame("Test");
Canvas c = new Canvas();
Graphics g;
c.setSize(400, 400);
f.add(c);
f.pack();
f.setVisible(true);
c.setVisible(true);
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g = c.getGraphics();
g.drawRect(10, 10, 40, 68);
}
}
Basically, this is not how painting in AWT works. Painting should be done within the context of a component's paint method. In AWT Canvas seems to be the preferred base component to use.
You should never use getGraphics, apart from been able to return null, it will only represent the Graphics context from the last paint cycle, anything added to it could be wiped about by newer paint events...which is probably happening to you.
Take a look at Painting in AWT and Swing for details about how painting works.
Having said all that, I would discourage you from using AWT based API as it was replaced by Swing some 15 years ago.
Take a look at Performing Custom Painting for more details about painting in Swing
You're kind of getting the idea, but there are a few standard design patterns of creating a game, for starters check out this code.
Basically, you'll need something called a game loop which will update and render to the display a certain amount of times every second (framerate or fps). When it renders, it will clear and redraw the image in a new location at a certain interval, if your fps was 60 you would be rendering (clearing, and redrawing) 60 times a second. We can also introduce more advanced concepts such as buffer strategies (shown in the example above) to reduce tearing and flickering.
To sum it up, you're kind of there, you just need to constantly do that g = c.getGraphics() so...
while (true) {
g = c.getGraphics();
// set color
// draw a rectangle
g.dispose();
}
Note how I added the dispose, this will just free up any unused memory. Just to clarify, this is by no means good code, but it will give you a place to start :)
The flickering is due to only having 1 screen, to stop this flickering you need a buffer strategy. Basically having two buffers is like having two screens, whilst you render on one 'screen' you can clear and draw the next step on the second screen and switch between the two buffers; this reduces the flickering.

Painting an image when key is pressed

I'm making a simple Java applet that displays a traffic light. If there are no keys being pressed the background is white. If you hit the "1", "2", or "3" keys on the numpad then the traffic light should change colors to respectfully: red, green, and yellow. It is not working because when I press any keys, nothing happens.
all isX booleans are initialized to false except for isReleased.
#Override
public void keyPressed(KeyEvent e) {
isReleased = false;
switch(e.getKeyCode()){
case KeyEvent.VK_NUMPAD1:
isRed=true;
break;
case KeyEvent.VK_NUMPAD2:
isGreen=true;
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
isReleased = true;
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(trafficLight, 0, 0, null);
if(isReleased==true){
g.drawImage(blank, 0, 0, this);
}else{
if(isRed==true){
g.drawImage(red, 0, 0, this);
}
if(isGreen==true){
g.drawImage(green, 0, 0, this);
}
}
}
NOTE
(updated) My full code can be seen here: http://pastebin.com/8ZNQUWJy
Let's ignore that fact that you code is incomplete, so it's impossible to know what you are extending from or if you've actually added a KeyListener.
KeyListener is notorious for being fickle about it's focus state. Basically, this means, KeyListener will only respond to keystrokes if the component it is registered to is focusable AND has keyboard focus...
A better solution would be to use the Key Bindings API, which provides better control over the focus level that will trigger key events.
You are also breaking the paint chain. Painting is a complex series of method calls, chaining together to produce the final result. By failing to call super.paint, you've broken this chain, introducing the possibility of paint artifacts.
You should also avoid overriding paint generally, but especially of top level containers, like windows, as they are not double buffered. It is recommended that instead, you extend from something JPanel or JComponent and override it's paintComponent method instead.
Take a look at Performing Custom Painting for more details.
Updated based on seeing full source
Avoid AWT based components (like Applet) the API is out of date and not many people use it any more, instead you should consider using a JApplet instead. But personally, I would avoid applets until you have a better understanding of the overall API.
Don't call setSize within an applet, the size is determined by the html tag which describes the applet to the browser
Your run method is pointless as it doesn't actually do anything useful and may actually be causing your application to "hang"
Your update method is only painting the trafficLight BufferedImage, but because you fail to call super.update, nothing else is painted. It would be better to grid rid of it and do your painting in the paint method, but make sure you are calling super.paint. But as I already said, you'd be better of using something like JPanel and overriding it's paintComponent method.
Take a look at Creating a GUI with Swing for more details
You may also find Why CS teachers should stop teaching Java applets of some worth...

Simple painting

I have an seemingly very simple task at hand. I have a grid (500x500 right now) I want to visualize as it is populated and I want to write a class in Java that makes this easy for me to do. I'm thinking something along the line of:
public class Screen {
...
public void plot(x,y) {
// change the color of pixel x,y to black
}
public void clear() {
// fill the screen with white
}
}
I have been looking around and quickly found Canvas in awt, however from what I have been able to figure out so far, this widget will only allow me to draw on to it by overriding its paint method. This is far from optimal in my case as this will require me to draw the entire grid every time I wish to do just plot one single pixel.
Is there any way to get canvas to just draw a single pixel rather than the entire canvas? Or some other way to accomplish what I look for here?
I would prefer to avoid having to use any external libraries.
You will need to override the paint method to display the entire grid.
However, what you can do is create a BufferedImage that flips the one pixel, and draw that entire image to the component in the paint method, using Graphics.drawImage().
Unfortunately you have to override paint() and render the entire grid every time paint() is called. That's how graphical components work - the windows system/OS may request to repaint the component at any time (eg. when the window is re-shown/resized/moved)

Overiding AWT and storing graphics

-Hi all! I'm making a Java applet that simulates wave interference, which I have almost finished (will license under GPL). However, I have two questions regarding the AWT paint cycle that I am having difficulty finding answers to.
I want to make an 'about' overlay that appears when I press a button. The way I want to do this is to draw over the entire applet window with my static message and legend objects. The problem is stopping the AWT components from drawing themselves in the foreground without using remove(). Is there a way I can stop AWT from drawing itself temporarily?
For my standing waves mode I want to have node and anti-node markers calculated and drawn to a secondary graphics every time the standing wave reaches a maximum amplitude (all of which I can do myself), but drawn to the primary graphics (and thus displayed) every paint cycle. Could someone explain the steps to do so? I imagine it would involve creating a second graphics object, drawing to it once, then drawing it to the primary graphics every cycle.
If you are able to answer either of my questions I would be very grateful!
Cheers, Jack Allison
Responding to your first question:
You can't disable the paint()/paintComponent() method if you've inlcluded it in your code. If its there, it runs. However, you can create a flag so that only if the flag is true, the stuff gets drawn. Let me show you what I mean:
boolean flag;
...
public void paintComponent(Graphics comp) {
if (flag) {
Graphics2D comp2D = (Graphics2D) comp;
//drawing statements
}
}
public void actionPerformed(ActionEvent event) {
flag = true;
repaint();
}

Categories

Resources