I am developing a simple game where have to write words. So I taught to make a TextArea where the words typed goes, to this I need a scroll to can see all words. But i have a render method that have this:
public void onRender(Graphics2D g) {
g.drawImage(imgBG, 0,0, null); //draws my background
g.setColor(Color.WHITE);
g.setFont(titulo);
g.drawString("Type the Word!", 260, 240);
g.setColor(Color.darkGray);
for(int i=0;i < wordFind.length();i++)
{
g.fillRect(inicioTraco+(60*i),yTraco,40,10);
}
if(tag_s == true)
{
tag_s = false;
g.setFont(titulo);
g.drawString("s",posicao, 100);
}
this.getMainWindow().add(new JTextArea("Test",10,20));
}
getMainWindow is a method that return my main JFrame, and i put this JTextArea to show the words.
But it is not appearing in my game.
I taught to make a white rect (fillrect) but it will not have scoll.
So I don't know what to do. Can someone clear my mind?
thanks.
Related
I am trying to make a chess engine as a fun project, but for that I really want to make a GUI. The problem is that I have no experience with this, so I am a little stuck. I managed to create the board, but there are two things I have no idea how to do and looking online just confuses me further.
How do I add the pieces to the board, based on what the board looks like in the computers memory. (so for example if the engine makes a move, I want that move to also happen on the gui, how would I link the two?)
How do I figure out what square the user is clicking on in the gui?
This is the code I have so far for the gui, it's not much, but it's honest work
private final JFrame gameFrame;
private Board board;
public Table() {
this.board = new Board();
this.gameFrame = new JFrame("Chess");
this.gameFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.gameFrame.setSize(527, 550);
JPanel panel = new JPanel() {
#Override
public void paint(Graphics g) {
boolean white = true;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (white) {
g.setColor(new Color(240, 217, 181));
}
else {
g.setColor(new Color(181, 136, 99));
}
g.fillRect(j * 64, i * 64, 64, 64);
white = !white;
}
white = !white;
}
}
};
this.gameFrame.add(panel);
this.gameFrame.setVisible(true);
}
I know I am probably asking questions with complicated answers, but I am just looking for something I can look up or some general directions
One way and perhaps the the most useful is to implement a mouseListenerand then get the x y position from one of the methods.
Write a class to extend MouseAdapter.
override the desired empty methods.
then add an instance of that class to the frame via addMouseListener (and perhaps addMouseMotionListener).
Then when you do some action with the mouse, you can get the coordinnates from the MouseEvent. It helps to put some print statements in each method to observe what is going on (what method is processing what mouse movement).
The above will serve to demonstrate the process. But later on you should actually add the listener on a JPanel and add the JPanel to the frame.
I am coding a game in Java. The first screen is the begin screen. On a mouse click, the screen is supposed to switch to a screen that lets you choose a character. Then, the next screen is the first game question. The character choosing screen isn't coming. It is just going to the first question. drawq is the boolean that determines if the question has been drawn. I had initialized it to false in the beginning of my code. Here is my mouselistener method, please help me find a way to get the screen that displays "Choose your character" and the image of the girl.
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
//background image
g.drawImage(theme.getImage(),0,0,WIDTH,HEIGHT,null);
//Choosing character screen
g.drawString("Choose your character", WIDTH-1550, HEIGHT/6);
g.drawImage(girl.getImage(),WIDTH-1550,HEIGHT/2,237,338,null);
//switching drawq to false
drawq=true;
//draw next question on mouse click
if(drawq==true) {
questions[whichquestion].draw(g);
drawq=false;
repaint();
}
It seems like you have got the order of your code mixed up, you set drawq to true and then immediately afterwards check if it's true, which will obviously always result in the if clause beeing run.
There are tons of tutorials for developing games on Java. Also here on SO there are many questions and answers. Just take a look at one or the other and let yourself be inspired.
An example of mouse input and screen output:
public class Main extends JPanel{
private int clicks = 0;
private Random rnd = new Random();
public static void main(String[] args){
var frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setContentPane(new Main());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
public Main(){
addMouseListener(new MouseInputAdapter(){
#Override
public void mouseClicked(MouseEvent e){
clicks = e.getClickCount();
repaint();
}
});
setPreferredSize(new Dimension(640, 480));
repaint();
}
#Override
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
g.drawString("Click your Mousebutton! One, two, three times or more ;-)", 20, 20);
if(clicks > 0) {
g.drawString("Clicks counted: " + clicks, 20, 40);
for(int i = 0; i < clicks; i++){
g.setColor(new Color(rnd.nextInt(256),rnd.nextInt(256),rnd.nextInt(256),255));
g.drawLine(20, 60 + i * 10, 100 + i * 20, 60 + i * 10);
}
}
}
}
I suggest that you go back to the drawing board. You should create a JFrame subclass that has a JLabel and a JImage on it. Then when the user clicks the button, just show that JFrame.
In gneeral, don't use a Graphics object outside of paintComponent(). And don't use drawImage() or drawText() unless you have a good reason. In this case, a JLabel and a JImage are much more appropriate for implementing the elements in the screen.
I am trying to draw a car as a polygon in swing and move it left and right when clicking button
The problem is that I can't display the buttons on the screen when running the program and can't make them works
And I Don't know how implement the buttons inside of the user interface when using polygon
Here is my code:-
package java2d;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Java2D extends JFrame{
int xValues[];
int yValues[];
private JButton Right, Left;
public Java2D() {
super( "Drawing lines, rectangles and ovals" );
setSize( 500, 300 );
setVisible( true );
}
public void paint( Graphics g ) {
int xValues[] = { 40, 100, 130, 230, 260, 320, 320, 40 };
int yValues[] = { 120, 120, 40, 40, 120, 120, 170, 170 };
Polygon polygon1 = new Polygon( xValues, yValues, 8 );
g.setColor(Color.blue);
g.drawPolygon( polygon1 );
Right = new JButton("Right");
Left = new JButton("Left");
Right.setSize(50, 50);
Left.setSize(50, 50);
Right.setLocation(100, 200);
Left.setLocation(200, 200);
g.add(Right);
g.add(Left);
}
public void actionPerformed(ActionEvent event) {
if(event.getActionCommand().equals("Right")){
for (int i=0; i<xValues.length;i++) {
xValues[i] = xValues[i] + 10;
yValues[i] = yValues[i] + 10;
}
}
if(event.getActionCommand().equals("Left")){
for (int i=0; i<xValues.length;i++) {
xValues[i] = xValues[i] + 10;
yValues[i] = yValues[i] + 10;
}
}
repaint();
}
public static void main(String[] args) {
Java2D application = new Java2D();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
}
THANKS
Many issues:
Variable names should NOT start with an upper case character.
Custom painting is done by overriding the paintComponent() method of a JPanel and then you add the panel to the frame. Read the section from the Swing tutorial on Custom Painting for more information and working examples to get you started. Start with the working code and modify it for your requirement.
Never create Swing components in a painting method. The painting method is continually invoked when Swing determines the component needs to be repainted, so you don't want to keep creating new buttons.
Typically to add buttons to the frame you would create a JPanel and add the buttons to the panel. Then you add the panel to the frame using frame.add(buttonsPanel, BorderLayout.PAGE_START). Then you would add your painting panel to the frame using frame.add(paintingPanel, BorderLayout.CENTER). Read the section from the Swing tutorial on Layout Managers for more information and examples.
Instead of attempting to update the values of the Arrays used to create the Polygon you should be using the translate() method of the Polygon.
Keep a reference to the Swing tutorial handy as it contains examples for most Swing basics.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm having a couple of different problems with my code, most of them are GUI based problems but i do have one actionevent problem. I will post my code in sections first then I will point out what the issue is specifically with each section. *note all of my code will be in order of how is actually in my IDE.
If you wish to copy my code without all of the other stuff here it is on pastebin: http://pastebin.com/HHjRRtGZ
My imports:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*; //Makes it a Japplet
import java.util.Random;
My Program Starts here:
public class Hangman extends JApplet implements ActionListener {
// How many times you can guess the wrong letter till you lose
static final int DEAD = 7;
private int errors; // amount of errors
private String message; // Message displaying either Error or Victory
private String information; // Secondary Message
private String RealWord; // The Real word
private StringBuffer GuessWord;// The Guessed word
private Button StartBtn; // The Restart Button
private Button GoBtn; // The Go Button
private TextField LetterBox; // The LetterBox
My ActionEvent:
public void actionPerformed(ActionEvent e){
if (e.getSource() == StartBtn){
initGame();
}
if (e.getSource() == GoBtn){
processTurn();
LetterBox.setText("");
repaint();
}
}
Problem One:
The problem that I am having with my Action event is that when I hit the StartBtn it does not reinitialize everything. Nothing is cleared. Nothing is done. It doesn't do anything. So that's the issue there.
My init() function (This is where one of my problems lie.
public void init() {
// Create a "Textbox" for the letter guessing
LetterBox = new TextField();
//Create my buttons and labels
StartBtn = new Button("Restart");
GoBtn = new Button("Go");
//Add the elements to the applet
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
p.add(StartBtn);
p.add(new Label("Guess a letter"));
p.add(LetterBox);
p.add(GoBtn);
add(p, BorderLayout.SOUTH);
//Make buttons event listeners
StartBtn.addActionListener(this);
GoBtn.addActionListener(this);
//Startup the Game
initGame();
}
Problem 2 (MAIN PROBLEM):
The problems I have with my Init code that affect my GUI is that the actual word guess area and the hangman area are kind of messed up. It's hard to explain, so i'll show you an image. The Backdrop for almost all of the form is completely transparent. So it just uses a still image of whatever it was on top of as it's back ground.
Problem 3:
There are some other issues with the image as you can see. The code is further down for those parts however. But as you can tell, the messages do not clear and just write over each other, even though I specify them to (which you will see further down).
Problem 4:
Now before you guess any letters, the word is hidden with a "" but when you guess a correct letter for the word it's supposed to replace the "" with the correct letter guessed. However it just put's it on top of it (you will see the code for this below as well).
This is the Game initializer
public void initGame() {
//Set the errors to 0
errors = 0;
//Enter the wordslist, separated by a | here
String str = "write|program|receive|positive|variables|temporary|good|bad|test";
String[] temp;
//delimiter
String delimiter = "\\|";
// given string will be split by the argument delimiter provided.
temp = str.split(delimiter);
//Create the Random Seed Generator
Random RandGenerator = new Random();
//Generate my Random Number
int randomInt = RandGenerator.nextInt(temp.length);
RealWord = new String(temp[randomInt]);
char positions[] = new char[RealWord.length()];
Right here is where it replaces the unguessed characters on screen with a "*".
for (int i = 0; i < RealWord.length(); i++) {
positions[i] = '*';
}
String s = new String(positions);
GuessWord = new StringBuffer(s);
LetterBox.setText("");
//Delete Messages
message = "";
information = "";
repaint();
}
My Painting function
#Override
public void paint(Graphics g) {
int BaseY = 250;
//THE HANGING STAND
if (errors > 0) { //1 Error
g.drawLine(90, BaseY, 200, BaseY); //The ground
g.drawLine(125, BaseY, 125, BaseY-100); //The bar going up
g.drawLine(125, BaseY-100, 175, BaseY-100); //The sidebar
g.drawLine(175, BaseY-100, 175, BaseY-75); //The Rope
}
//THE PERSON
if (errors > 1) {
g.drawOval(170, BaseY-75, 10, 12); // The Head
}
if (errors > 2) {
g.drawLine(175, BaseY-62, 175, BaseY-45); // The Body
}
if (errors > 3) {
g.drawLine(165, BaseY-65, 175, BaseY-55); // Left Arm
}
if (errors > 4) {
g.drawLine(185, BaseY-65, 175, BaseY-55); // Right Arm
}
if (errors > 5) {
g.drawLine(170, BaseY-30, 175, BaseY-45); //Left Leg
}
if (errors > 6) { //7 Errors
g.drawLine(175, BaseY-45, 180, BaseY-30); // Right Left
}
//Show Messages/Errors
g.drawString(message, 40, BaseY+25);
g.drawString(information, 25, BaseY+45);
g.drawString(new String (GuessWord), 140, BaseY-120);
g.drawString(new String("WELCOME TO HANGMAN!"), 75, 40);
}
This is where alot of the magic happens. This is the processTurn Function
private void processTurn() {
String s, t;
char a;
s = LetterBox.getText();
a = s.charAt(0);
if (!Character.isLetter(a)) {
message = "Only enter letters please.";
return;
}
if (s.length() > 1) {
message = "One letter at a time please.";
return;
}
//Check if letter has been used already
t = new String(GuessWord);
if (t.indexOf(s) != -1) {
message = "You have already guessed with that letter!";
return;
}
//If the letter you guessed does not occur in the Real Word
if (RealWord.indexOf(s) == -1) {
message = "";
errors++;
if (errors==DEAD) {
message = "Sorry, you lose";
information = "Click restart to try again!";
//INSERT MOVING HANGMAN HERE.
}
return;
}
This is where the "*" is supposed to be replaced with the correctl guessed letter but it doesn't work correctly!
//Replace stars in the Guessed Word with the found letter
for (int i = 0; i < RealWord.length(); i++) {
if (RealWord.charAt(i) == a) {
GuessWord.setCharAt(i, a);
}
}
t = new String(GuessWord);
//If all of the stars have been filled, then you win!
if (t.indexOf('*') == -1) {
message = "You have won!";
return;
}
//Delete the Message
message = "";
repaint();
}
Main Function
public static void main(String[] args) {
JFrame frame = new JFrame();
JApplet applet = new Hangman();
applet.init();
applet.start();
frame.add(applet);
frame.setSize(300, 400);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Any and all assistance will be greatly appreciated :) Thanks in advance!
This is caused by the basic fact that you have broken the paint chain.
Painting in AWT/Swing is made of a chain of method calls. If you neglect to maintain this chain, you start ending up with paint artifacts, in the form you are seeing.
The Graphics context is a shared resource, that is, every component painted during any given paint cycle will be given the same Graphics resource. Each component is expected to prepare the Graphics context before painting to it...
To fix the problem, in all your paint methods, you should be calling super.paint(g) to ensure that the paint chain is maintained and that the Graphics context is preapred for the individual components painting needs.
Having said that. It is not recommended to override paint of top level containers. Instead, it is recommended that you perform your custom painting using something like a JPanel and override it's paintComponent method instead (ensuring that you call super.paintComponent as well!)
This has a least two basic benefits. The first is, you can know decide where the panel should be displayed, for example, you could add it to an JApplet or JFrame or other container as you see fit. It is double buffered by default. This means you won't see any flicker when the painting is updated.
You should consider breaking your application down into small panels, focusing on each of the components needs separately. This will help reduce the complexity of your application and make it easier to manage the individual needs of each section of your application.
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details
The problem is that you're painting directly on JApplet. You should not paint directly on top level container such as JFrame or JApplet. Instead, use JComponent or JPanel. Override paintComponent() for painting rather than paint() and don't forget to call super.paintComponent(g).
Take a look at Performing Custom Painting tutorial for more information.
Consider refactoring your code by moving all the current logic and painting into a new JPanel which will be used as applet content. Then, add this panel to the applet.
EDIT:
The source of the problem is not calling super.paint() in you painting implementation. Overriding paint() is not necessary and usually not recommended in many Swing applications. JComponent.paint() (a superclass for all Swing components) handles painting the content, borders, and children of a Swing component. And by neglecting a call to super.paint() you are disrupting the painting of all these details.
Take a looks at A Closer Look at the Paint Mechanism for more details about painting cycle.
I am trying to add a JLabel under the boards that is painted with graphics. I set the x and y position of JLabel somewhere under the board
pName = new JLabel("Yoooooo");
pName.setBounds(180,500,50,50);
this.add(pName);
However I can't view it when I run the code. What can be the reason?
Edit: Now I can view it thx to Andrew but I can't locate it to the position that I want.
JLabel should be under the board.
pName.setBounds(180,500,50,50);
seems not working. Why can it be?
public class EnemyPanel extends JPanel{
private char enemyBoard[][] = new char[10][10]; //to keep state of squares
private Rectangle r[][] = new Rectangle[10][10];//to give coordinates and boundaries to squares
private int size;
private JLabel pName;
public EnemyPanel()
{
size=Constant.rectSize;
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
enemyBoard[i][j]='*'; //initialization type
r[i][j]= new Rectangle(j*size+30,i*size+30, size, size);
}
}
pName = new JLabel("Yoooooo");
pName.setBounds(180,500,50,50);
this.add(pName);
}
public void paint(Graphics g){
super.paintComponent(g);
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(enemyBoard[i][j]=='!'){
//hit square's color is changed to white
g.setColor(Color.white);
}
else if(enemyBoard[i][j]=='$')
//miss square's color is changed to gray
g.setColor(Color.gray);
else
//undiscovered ones are green
g.setColor(Color.green);
g.fill3DRect((int)r[i][j].getX() ,(int)r[i][j].getY(),(int)r[i][j].getWidth(), (int)r[i][j].getHeight(), true);
}
}
}
}
Here is the output:
Once you override paint(Graphics g) you are on your own on painting the component. This means that no matter what other stuff you do outside paint, it may not count much as the real paint happens in your custom implementation and not in the default JPanel one.
My first problem was that I couldn't view the JLabel component.
According to Andrew's comment, I solved this problem.
If you are using other components in your panel, you should use paintComponent other than paint.
Secondly, I couldn't view my JLabel where I wanted. So In order to set a specific position to JLabel, you should set the JPanel layout to null.
this.setLayout(null) solved my second problem.