Java scroll text on canvas - java

I'm making an application where I need to scroll some text on a java.awt.Canvas - at the moment I'm doing this by constantly calling the repaint() method, and overriding the paint() method in Canvas to adjust the position each time the method is called and then draw the string at the given position.
This works, but it really eats through CPU something silly for something so simple. Is there a better, hardware accelerated way to do the task? I've tried using VolatileImage but for some reason that made the performance noticeably worse.
I need to use Canvas not JPanel - I'm using VLCJ in the same project, and it needs a heavyweight component on which to play the video.

You may be able to use Double Buffering and Page Flipping in this context.
Addendum: You might look at pre-rendering the full text into a depth-compatible BuffreredImage; drawImage() does better of it doesn't have to scale or change depths.

Related

JavaFX Canvas scaling without anti-aliasing

I'm working on a painting program and I'd like to be able to scale (zoom) my JavaFX canvas without anti-aliasing.
After some research, I came across this: JavaFX ImageView without any smoothing which explains the different workarounds.
I decided to implement workaround #4, which is to read the pixels from a snapshot of the canvas and scale it up and draw to an ImageView. However, this is not practical as performance is really bad, as demonstrated here by drawing moderately fast strokes on a very small canvas (640,480):
I suppose I could implement a smoothing algorithm for the strokes, but I'm not sure how long it would take before I came to another stop because of this performance.
Will we ever get a: canvas.setInterpolation(Interpolation.NEAREST_NEIGHBOUR)? Is there another way to implement this with even better performance?
My last resort is to go back to Swing which actually can be set to disable interpolation.

The best way of using graphics for games

I am new to java and programming in general,and i am trying to write a little shooting game with a spaceship and aliens, but having a lot of trouble with the graphics. It seems that I am mixing a lot of different kind of components.
How should I do it right?
- Should I use Swing JFrame and then add it a Graphics object?
- Should I make a panel first and add the graphics on to it instead?
- Or maybe should I use a canvas instead of a JPanel?
There are a lot of options, and searching the net for answers makes me very confused. Some advise to use the paint() method while others demonstrates code while using the paintComponent()...
What is the preferred way in the right order for the graphics to be laid and what classes should I use?
For serious gaming, don't use Swing but rather other more game-specific GUI libraries such as the LWJGL. For simple Games, Swing is OK, but be sure to read the graphics tutorials first as your assumptions on how to draw may need to be changed (I know mine were). For instance you would not use a Graphics class field but would usually draw passively in a JComponent's paintComponent method.
For simple games, Swing is fine and you can rely on the followings:
Use Swing and forget about AWT. You will get far better results with a lot less code.
Use Swing Timer to pace your game
For each of your components, extends JComponent or JPanel and override paintComponent. In paintComponent perform only drawing operations (do not update your model or modify the state of your component).
Whenever when you want to draw something, modify your components state and then invoke repaint()
To handle layers, you can always use JLayeredPane
I can see the sense of using a game API as suggested by #Hovercraft, but feel that many simple games can do without it.
I agree with the first 2 points of #Guillaume, but would tend to go in a different direction after that.
Let us assume the game:
Is a fixed size (i.e. non-resizable).
Has no components appearing over it.
In that case, I would tend to do the rendering in a BufferedImage that is displayed in a label.
Answers to specific questions
Should I use Swing JFrame and than add it a Graphics object?
That would not compile. So ..no.
Should I make a panel first and add the graphics on to it instead?
That is basically what Guillaume is suggesting, though I prefer using an image as the canvas on which to paint.
Or maybe should I use a canvas instead of a JPanel?
If by 'canvas' you mean java.awt.Canvas then no.
If you mean a java.awt.image.BufferedImage then yes.
Some advise to use the paint() method while others demonstrates code while using the paintComponent()...
This is a common confusion since there is so much old and bad code out there in the World Wild Web.
The only components that overriding paint(Graphics) would work with are components of the AWT & Swing top-level containers such as JFrame, JApplet or JWindow.
AWT is last millennium's GUI component toolkit. We should use Swing this millennium.
It is unusual for an entire GUI to be custom painted. Instead it might be added as the major component amongst others that report player health, lives remaining, score etc. For that (and other) reasons, it is better to render to a 'non top-level container' which would leave us looking at doing custom painting in a JComponent or JPanel.
For custom painting in an extended panel or component, override paintComponent(Graphics). That is the correct way to do custom painting for those components.
Other tips
Each object of the game (e.g. Ship, Enemy, Missile) should know how to draw itself. Keep a reference to each of the game elements in the painting routine, and simply call gameElement.paint(Graphics) (or Graphics2D) on the instance of graphics it is painting.
If the game elements are drawn from Java-2D based Shape instances, or if a Shape can be defined from the existing sprite images, collision detection becomes simple. For details see:
This answer to Get mouse detection with a dynamic shape
This answer to Collision detection with complex shapes
I had to implement a lost-vikings like game for a course project and not having a single idea how to do it, had the exact same questions in mind.
I ended up writing methods that are responsible for drawing different elements(i.e., one to draw enemies, one for missiles, etc...), and then called them in paint() method. I called repaint() method in my main loop to redraw everything.
I am not sure if this is a good practice, but it worked. You can check the code here, though, I must warn you that it is a "damn, i must get it done" project. You should specifically have a look at GameFrame.java.

Suggestion for implementing a drawing program - UML designer

This program will have an infinite canvas (ie as long as the user scrolls, it becomes bigger) with a tiled background image, and you can drag and drop blocks and draw arrows between blocks. Obviously I won't use a layout manager for placing blocks and lines, since they will be absolutely positioned (any link on this, possibily with a snapping feature?). The problem arises with blocks and lines. Basically I'll have two options:
Using a simple layout for each building block. This is the simplest and clearest approach, but does it scale well when you have hundreds of objects? This may not be uncommon, just imagine a database with 50 tables and dozens of relationships
Drawing everything with primitives (rectangles, bitmaps, etc). This seems too complicated (especially things like text padding and alignment) but may be more scalable if you have a large number of objects. Also there won't be any event handler
Please give me some hints based on your experience. I have never drawn with Java before - well I did something rather basic with PHP and on Android. Here is a simple preview
DISCLAIMER
You are not forced to answer this. I am looking for someone who did something like this before, what's the use of writing I can check an open source project? Do you know how difficult it is to understand someone else's code? I'm talking about implementations details here... Moreover, there is no guarantee that he's right. This project is just for study and will be funny, I don't want to sell it or anything and I don't need your authorization to start it.
Measuring and drawing text isn't such a pain, since java has built in classes for doing that. you may want to take a look at the 2D Text Tutorial for more information. In fact, I did some text drawing computations with a different graphics engine which is much more primitive, and in the end it was rather easy (at least for the single-line drawing, for going multiline see the previous link).
For the infinite canvas problem, that's also something I always wanted to be able to do. A quick search here at stackoverflow gives this which sounds nice, althought I'm not sure I like it. What you can do, is use the way GIMP has a scroll area that can extend as you move - catch the click of the middle mouse button for marking the initial intention to move the viewport. Then, when the mouse is dragged (while the button is clicked) move the viewport of the jscrollpane by the offset between the initial click and the current position. If we moved outside the bounds of the canvas, then you should simply enlarge the canvas.
In case you are still afraid of some of the manual drawing, you can actually have a JPanel as your canvas, with a fixed layout. Then you can override it's paint method for drawing the connectors, while having child components (such as buttongs and text areas) for other interaction (and each component may override it's own paint method in case it wants to have a custom-painted rect).
In my last drawing test in java, I made an application for drawing bezier curves (which are basically curves made of several control points). It was a JPanel with overidden paint method that drew the curve itself, and buttons with custom painting placed on the location of the control points. Clicking on the control point actually was clicking on a button, so it was easy to detect the matching control point (since each button had one control point associated with it). This is bad in terms of efficiency (manual hit detection may be faster) but it was easy in terms of programming.
Anyway, This idea can be extended by having one child JPanel for each class rectangle - this will provide easy click detection and custom painting, while the parent will draw the connectors.
So in short - go for nested JPanels with custom drawing, so that you can also place "on-canvas" widgets (and use real swing widgets such as text labels to do some ready drawing) while also having custom drawing (by overriding the paint method of the panels). Note that the con of this method is that some swing look-and-feel's may interfere with your drawing, so may need to mess a bit with that (as far as I remember, the metal and nimbus look-and-feel's were ok, and they are both cross-platform).

How to get the image center, strech, fill, tilt in J2ME?

How to get these effects in a J2ME project?
I need a similar effect like CSS background like we write:
background:#fff url(img.png) repeat-x;
I need this kind of thing in J2ME. Can I do it?
I"ve never used J2ME, but I assume it supports basic Graphics functionality. Therefore you should be able to used the concepts found in the paintComponent() method of Background Panel to do your custom painting.
The graphical stuff you can do out of the box in J2ME is anything found in the javax.microedition.lcdui.Graphics. If you want an image repeated across the screen, you'll need to paint it repeatedly in a loop, in your paint() method. You can't rotate an image through small angle; you can rotate through 90 degree angles using javax.microedition.lcdui.game.Sprite.
There's no method for scaling in the API, however you could copy/paste a function like this; beware, this is likely to eat up a lot of memory.

Zoom in Java Swing application

I am looking for ways to zoom in a Java Swing application. That means that I would like to resize all components in a given JPanel by a given factor as if I would take an screenshot of the UI and just applied an "Image scale" operation. The font size as well as the size of checkboxes, textboxes, cursors etc. has to be adjusted.
It is possible to scale a component by applying transforms to a graphics object:
protected Graphics getComponentGraphics(Graphics g) {
Graphics2D g2d=(Graphics2D)g;
g2d.scale(2, 2);
return super.getComponentGraphics(g2d);
}
That works as long as you don't care about self-updating components. If you have a textbox in your application this approach ceases to work since the textbox updates itself every second to show the (blinking) cursor. And since it doesn't use the modified graphics object this time the component appears at the old location. Is there a possibility to change a components graphics object permanently? There is also a problem with the mouse click event handlers.
The other possibility would be to resize all child components of the JPanel (setPreferredSize) to a new size. That doesn't work for checkboxes since the displayed picture of the checkbox doesn't change its size.
I also thought of programming my own layout manager but I don't think that this will work since layout managers only change the position (and size) of objects but are not able to zoom into checkboxes (see previous paragraph). Or am I wrong with this hypothesis?
Do you have any ideas how one could achieve a zoomable Swing GUI without programming custom components? I looked for rotatable user interfaces because the problem seems familiar but I also didn't find any satisfying solution to this problem.
Thanks for your help,
Chris
You could give a try to the JXLayer library.
There are several tools in it, which could help you to make a zoom. Check the examples shown here. I would recommend you to read more about the TransformUI, from this library. From the example, it seems like it could help solving your problem.
Scaling the view is easy enough; transforming mouse coordinates is only slightly more difficult. Here's an elementary example. I'd keep JComponents out, although it might make sense to develop an analogous ScaledComponent that knows about the geometry. That's where #Gnoupi's suggestion of using a library comes in.
hey you can try this if you want to zoom a image like any other image viewer the use a JPanel draw an image using drawImage() method now create a button and when you click the button increase the size of the panel on the frame it appears as if the image is being viewed in Zoom
You might find Piccolo2D.java API useful: http://code.google.com/p/piccolo2d/
It is very simple.
It touts in particular its smooth zooming. You essentially make a "canvas" that can contain various elements, and can then zoom by just holding right-click and panning the mouse back and forth.
I worked on a team that used it to create this: http://sourceforge.net/apps/mediawiki/guitar/index.php?title=WebGuitar#EFG.2FGUI_Visualizer
The nodes you see there are clickable links themselves.
Since Java 9, there are VM arguments (actually meant to be used for high dpi scaling) that can render a application with a higher scaling factor:
java -Dsun.java2d.uiScale=2.0 -jar MyApplication.jar
Or:
java -Dsun.java2d.win.uiScaleX=2.0 -Dsun.java2d.win.uiScaleY=2.0 -jar MyApplication.jar

Categories

Resources