Get an input from the user using graphics - java

I'm writting my first game and i want to add the name of the user to the high score chart. What is the best way to get the input from the user? except using JOption.
Needless to specify that i am drawing my game continuously. Maybe i can use JTextField?

Assuming you are rendering your game onto a JComponent, yes you can just add a JTextField onto your renderer component. Or you can render your own text field if you want to customize the look of everything.
To do a custom renderer:
Somewhere in your code, store the location of the text input box.
Rectangle r = new Rectangle(200,200,250,30);
String text = "";
In your rendering code:
public void paintComponent(Graphics g){
g.setColor(Color.blue);
g.fillRect(r.x, r.y, r.width, r.height);
g.setColor(Color.black);
// You can play with this code to center the text
g.drawString(text, r.x, r.y+r.height);
}
Then you just need to add a keylistener somewhere in your constructor.
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
text+=e.getKeyChar();
//you might not need this is you are rendering constantly
repaint();
}
});

Related

How to draw a string in swing using the current look and feel?

I'm writing a custom JComponent and it will draw some text from a string.
Currently the text drawing code looks like this:
#Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Rectangle bounds = graphics.getClipBounds();
int maxAscent = graphics.getFontMetrics().getMaxAscent();
graphics.setColor(Color.BLACK);
graphics.drawString(text,bounds.x,bounds.y+maxAscent);
}
However, this draws aliased text. So I googled drawing antialiased text and found I could add these lines:
graphics2D.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
But then I thought... what else am I missing? And what if the user disables antialiased text and the current look and feel honors this but my code does not.
I want to draw the text as the current look and feel would draw the text. How can I do that?
You can use the desktop settings. It is explained here: http://docs.oracle.com/javase/7/docs/api/java/awt/doc-files/DesktopProperties.html#awt.font.desktophints
Instead of using
graphics2D.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
use
Toolkit tk = Toolkit.getDefaultToolkit();
Map map = (Map)(tk.getDesktopProperty("awt.font.desktophints"));
if (map != null) {
graphics2D.addRenderingHints(map);
}

how to draw a black rectangle over Image icon?

in my application I have a cross road picture in the background and I want to draw traffic lights on the top of it (black rectangle with 3 circles)
The problem is, I cannot see the rectangle at all, as if it was under the image or something. And if I switch the order in which the items are painted, I get all black image.
Do you have any idea how this can be solved?I am new to graphics and searched similar questions, but none helped me.
Thank you.
public MainFrame() throws HeadlessException {
super("semafor");
crossroad = new ImageIcon("cross.png");
initFrame();
initComponents();
sem1 = new Semafor(true, 100, 100);
add(sem1);
repaint();
setVisible(true);
}
//here I paint the image
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(crossroad.getImage(), 0, 45, this);
}
//and in class Semafor i paint the actual traffic lights
#Override
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.darkGray);
//and then the circles
}
The first thing I'm noticing is that you are calling <unknown>.getWidth() and <unknown>.getHeight() for the rectangle size. If it's covering the entire image, this suggests that it is getting that width and height from the panel it is being drawn on.
A simple stack trace,
(new Exception).printStackTrace();
or
Thread.dumpStack();
will tell you as much. You could also query the width and height with a System.out call to verify that you're getting the values you're expecting, or, if this really gets out of control, learn to use JUnit and the assert statement. Honestly, though, it looks like you're just accidentally calling the wrong method.

Changing color of a drawn oval

I create an object called "City"
City city = new City (name, rec, g);
The object's constructor looks like this:
public City (String name, Rectangle r, Graphics g){
this.name = name;
this.r = r;
this.g = g;
}
By creating this object i also draw an oval on an uploaded picture, and set it's colour to BLUE. Here's how I draw the object:
g = (Graphics2D) window.lblNewLabel.getGraphics();
g.setColor(Color.BLUE);
g.fillOval(mouseX, mouseY, 15, 15);
I would like to be able to change that colour later, after clicking on the oval itself.
I try to call this function, but it doesn't work:
public void isClicked(){
clicked = true;
this.color = Color.RED;
this.g.setColor(Color.PINK);
}
How to change a colour of an existing object?
Using getGraphics() on a component causes a transient graphics Object to be used on the component itself. Any subsequent calls to repaint will erase the painting done using that object.
Change the color by overriding the paintComponent method. Save the Color variable as a class member variable and use it to determine the oval color in the method.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(savedColor);
g.fillOval(mouseX, mouseY, 15, 15);
}
Don't use getGraphics() to do painting, that painting is only temporary and will be lost the next time Swing determines a components needs to be repainted.
Check out Playing With Shapes for other ideas on doing painting.
You could use a ShapeIcon which allows you to change the color of the icon. The icon could be painted in the paintComponent() method of your label.
Or you could use ShapeComponent which uses a ShapeIcon. Then you can just add the component to the label like any other component.
I would like to be able to change that colour later, after clicking on the oval itself
The ShapeIcon would be added to a JLabel. Then you can just add a MouseListener to the label of the ShapeComponent to change the color of the icon.
When you have drawn objects with a Graphics object, they are then rendered on the screen. You can't change the color of them directly, instead you will have to repaint your graphics any time when you want to change them. If you want to keep track of the colors for the objects, you will have to store the data in some kind of variable and use it when drawing.

Java image display issue

Dear wonderful people of stackoverflow
A group of my friends are attempting to make a level editor in Java.
We have a Jpanel instead of a Jframe and we are trying to put small images onto the Jpanel from a filepath saved as a string. In the end we want a list of images that you can just drop on. So far we have tried a few methods with no luck.
We can load the images, however we can't get these images to actually display, What would be the best means of solving said problem?
below is a sample of what we have so far.
EnemyPlacementGrid = new JPanel();
EnemyPlacementGrid.addMouseListener(new MouseAdapter() {
//#Override
public int mouseX;
public int mouseY;
public void mouseClicked(MouseEvent arg0) { //what happens when you click in the EnemyPlacementGrid
System.out.println("Correct Area for placement");
mouseX = arg0.getX();
mouseY = arg0.getY();
//System.out.println("X:" + mouseX + ", Y:" + mouseY );
Enemy newEnemy = workingEnemy.cloneSelf();
newEnemy.setLocation(mouseX, mouseY);
System.out.println("newEnemy object: " + newEnemy);
System.out.println(newEnemy.weaponList);
currentWave.addEnemy(newEnemy);
System.out.print(currentLevel);
}
});
Any and all help is greatly appreciated.
UPDATE:
As of now I have an image appearing, however I can't update said image. Note code below:
public void run() {
try {
BufferedImage img = ImageIO.read(new File(IMG_PATH));
ImageIcon icon = new ImageIcon(img);
WaveScreen frame = new WaveScreen();
JPanel panel = (JPanel)frame.getContentPane();
JLabel label = new JLabel();
label.setIcon(new ImageIcon("images/map_on.png"));// your image here
panel.add(label);
frame.setVisible(true);
panel.add(label);
panel.repaint();
} catch (Exception e) {
e.printStackTrace();
}
update, method tried from comments:
Graphics2D g = null;
Graphics2D g2 = (Graphics2D)g;
Image imageVariable = new ImageIcon("images/map_on.png").getImage();
g.drawImage(imageVariable, mouseX, mouseY, null);
Well, i'd say to try using Graphics, meaning you need to override the paint method; i'd recommend that you put the mouseX and mouseY as global variables though…
// creating global image variable for use later
Image imageVariable = new ImageIcon("image path").getImage();
public void paintComponent(Graphics g) {
// here you could either create a Graphics2D object
// Graphics2D g2 = (Graphics2D)g;
// or you could use the g parameter as it is, doesn't matter.
// use the global variable for the image to be drawn onto the screen
// use the global value of the mouseX and mouseY for where you click the mouse
// to place the image, and this should be it
g.drawImage(imageVariable, mouseX, mouseY, null);
}
Hope this helps!
If the game is simple, user2277872's solution will work and you can use graphics2D from java. However, if you are planning on a more sophisticated game (lots of interaction, lots of textures), then the default Java framework for 2D graphics will prove to be too slow.
If you are planning on such a game, I can highly recommend either learning OpenGL or using an existing framework for graphics, such as
JMonkeyEngine (http://jmonkeyengine.com/)
or
Slick (http://slick.cokeandcode.com/index.php)
More information: What should I use to display game graphics?

How to treat a shape painted with an algorithm like an object?

Ok dear folks, i've got this question and i don't really know a certain way to solve it.
I'm doing like a "Paint application" in java, i know everything is ready, but I need to paint the shapes with Computer Graphics Algorithms.
So, the thing is, once the shape is painted in the container how could I convert it like sort of an "Object" to be able to select the shape and move it around (I have to move it with another algorithm) I just want to know how could I know that some random point clicked in the screen belongs to an object, knowing that, I would be able to fill it(with algorithm).
I was thinking that having a Point class, and a shape class, if i click on the screen, get the coordinates and look within all the shapes and their points, but this may not be very efficient.
Any ideas guys ?
Thanks for the help.
Here is some of my code:
public class Windows extends JFrame{
private JPanel panel;
private JLabel etiqueta,etiqueta2;
public Windows() {
initcomp();
}
public void initcomp()
{
panel = new JPanel();
panel.setBounds(50, 50, 300, 300);
etiqueta = new JLabel("Circulo Trigonometrico");
etiqueta.setBounds(20, 40, 200, 30);
etiqueta2 = new JLabel("Circulo Bresenham");
etiqueta2.setBounds(150, 110, 200, 30);
panel.setLayout(null);
panel.add(etiqueta);
panel.add(etiqueta2);
panel.setBackground(Color.gray);
this.add(panel);
this.setLayout(null);
this.setVisible(true);
this.setSize(400,400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.red);
g2d.setStroke(new BasicStroke(2));
dibujarCirculo_bresenham(g2d, 50, 260, 260);
dibujarCirculo_trigonometrico(g2d, 50, 130, 200);
}
/*This functions paints a Circle*/
public void dibujarCirculo_trigonometrico(Graphics g,int R,int xc,int yc)
{
int x,y;
for (int i = 0; i < 180; i++) {
double angulo = Math.toRadians(i);
x = (int) (Math.cos(angulo)*R);
y = (int) (Math.sin(angulo)*R);
g.drawLine(x+xc, y+yc, x+xc, y+yc);
g.drawLine((-x+xc), (-y+yc), (-x+xc), (-y+yc));
}
}
I assume that any image is a valid (isn't constrained to a particular set of shapes). To get an contiguous area with similar properties, try using a flood fill.
To colour in or move a particular shape around, you can use flood fill to determine the set of pixels and manipulate the set accordingly. You can set a tolerance for similar hue, etc so that it's not as rigid as in Paint, and becomes more like the magic selection tool in Photoshop.
There are a couple of approaches to take here depending on what precisely you want.
1) is to have objects, one for each drawn thing on screen, with classes like Circle and Rectangle and Polygon so on. They would define methods like paint (how to draw them on screen), isCLickInsideOf (is a click at this point on screen contained by this shape, given size/position/etc?) and so on. Then, to redraw the screen draw each object, and to test if an object is being clicked on ask each object what it thinks.
2) is, if objects have the property of being uniform in colour, you can grab all pixels that make up a shape when the user clicks on one of the pixels by using a floodfill algorithm. Then you can load these into some kind of data structure, move them around as the user moves the mouse around, etc. Also, if every object is guaranteed to have a unique colour, you can test which object is being clicked on by just looking at colour. (Libraries like OpenGL use a trick like this sometimes to determine what object you have clicked on - drawing each object as a flat colour on a hidden frame and testing what pixel colour under the mouse pointer is)

Categories

Resources