I have made a Snake project in which I used a grid layout
with width 20 and height 20. The problem is that when I want to access any square in the panel, it gets the square with the reversed coordinates. For example: when I use lightMeUp() method, which can change the color of the square, if I choose to color the square with coordinates (1,2) it will color instead (2,1) , and not only that but
other functions inside my project are also affected like this. Like for example when I try to color the positions which are traversed by the snake I have to reverse the coordinates in order to get the right squares colored. I will leave here some code that will show how I built the grid and the threads:
import java.awt.GridLayout;
import java.util.ArrayList;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class Window extends JFrame{
public static ArrayList<ArrayList<DataOfSquare>> Grid;
public static int width=20;
public static int height=20;
public Window() {
//Creates the arraylist that'll contain the threads
Grid=new ArrayList<ArrayList<DataOfSquare>>();
ArrayList<DataOfSquare> data;
//Creates Threads and its data and adds it to the arrayList
for(int i=0;i<height;i++) {
data=new ArrayList<DataOfSquare>();
for(int j=0;j<width;j++) {
DataOfSquare c=new DataOfSquare(2);
data.add(c);
}
Grid.add(data);
}
//Setting up the layout of the panel
getContentPane().setLayout(new GridLayout(20,20,5,5));
//Start and pauses all threads, then adds every square of each thread to the panel
for(int i=0;i<height;i++) {
for(int j=0;j<width;j++) {
getContentPane().add(Grid.get(i).get(j).square);
}
}
//initial position of the snake
Tuple position=new Tuple(5,5);
//passing this value to the controller
ThreadsController c=new ThreadsController(position);
//Let's start the game
c.start();
//Links the window to the keyboardListener
this.addKeyListener((KeyListener) new KeyboardListener());
}
}'
I also have other classes inside this project, but I don`t think they have anything to do with this problem so I showed just the code responsible for the grid layout.
There are no errors in my code, the code is doing well if I reverse the coordinates but I just do not understand why it is working like this.
What do I have to do in order to have the coordinates in the right place ?
Related
Hi all,
I'm fairly new to using GUI in java and I'm supposed to create a grid. However, I'm not very sure how to use JLabels, JFrames etc or how to even start. As such, can someone explain it in a 'simplified' manner or briefly go over how to start? The description is as follows:
Write the class GUICF that inherits CFGame. ConsoleCF is a graphical implementation of the
Connect Four game. GUICF should have the following fields, contructors, methods, and inner
class.
The private field
private GameBoard this board;
represents the graphics for the 6 × 7 board, but not the buttons.
The constructor
public GUICF(CFPlayer ai)
sets up and starts a human vs. AI game, where the red player (the player who goes first) is randomly
decided.
The constructor
public GUICF(CFPlayer ai1, CFPlayer ai2)
sets up and starts an AI vs. AI game, where the red player (the player who goes first) is randomly
decided.
A human vs. AI game and an AI vs. AI game creates slightly different GUIs. A human vs. AI game
will have a graphical interface like Figure 1. At each turn, the AI makes the move automatically
and the human player’s move is specified through clicking a button. An AI vs. AI game will have
a graphical interface like Figure 2. When you click the “Play” the next AI makes the next move.
The private method playGUI
private boolean playGUI(int c)
plays the column c. So the internal game logic inherited from CFGame and the displayed board
represented in this_board must be updated. If c is a column that can be played, play the column
and return true. Otherwise return false and do not update the state of the game.
Write the private class
private class GameBoard extends javax.swing.JPanel {
private GameBoard() {
// initialize empty board
...
}
private void paint(int x, int y, int color) {
//paints specified coordinate red or black
...
}
}
that represents the game board. In real life, the game pieces are circular, but in GameBoard they
can be square. These square pieces can be done with 6*7=42 JLabels and a GridLayout. (You
may want to use setOpaque(...) with the JLabels.)
The GameBoard does not include the buttons.
So far, my code is essentially useless, but here it is anyway:
package hw4;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class GUICF extends CFGame{
private GameBoard this_board;
private class GameBoard extends javax.swing.JPanel {
private JFrame frame;
private int x = 7;
private int y = 6;
private GameBoard() {
frame = new JFrame("CF");
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(6, 7));
for(int i = 0; i < y; i++) {
for(int j = 0; j < x; j++) {
JLabel shape = new JLabel();
shape.setOpaque(true);
shape.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.add(shape);
}
}
add(panel, BorderLayout.CENTER);
panel.setVisible(true);
frame.setContentPane(panel);
frame.setSize(700, 600);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void paint(int x, int y, int color) {
}
}
}
Any assistance is much appreciated.
I want to use Prefuse to visualise a graph. I followed their tutorial and tried their sample application. Its sourcecode can be found here
However, even if I simply copy the full code, the resulting graph does not look as displayed in the tutorial. It is only half visible, stuck in JPanel's upper left corner. Some parts of it are missing becuase they would have to be displayed outside the panel.
I tried with some graphs of my own, but I keep running into the same phenomenon.
I suppose this is not expected behaviour, but I have no idea where to hunt for the problem. I don't know if this is a problem with Swing(x) or prefuse or ... ?
Update:
This is the revised code. I did not change much from the example, only added what trashgod suggested.
package visualise;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.layout.graph.ForceDirectedLayout;
import prefuse.activity.Activity;
import prefuse.controls.DragControl;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.data.Graph;
import prefuse.data.io.DataIOException;
import prefuse.data.io.GraphMLReader;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;
public class PrefuseExample {
public static void main(String[] argv) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// -- 1. load the data ------------------------------------------------
// load the socialnet.xml file. it is assumed that the file can be
// found at the root of the java classpath
Graph graph = null;
try {
graph = new GraphMLReader().readGraph("../../resources/visualisation/prefuse/Prefuse-master/data/socialnet.xml");
} catch ( DataIOException e ) {
e.printStackTrace();
System.err.println("Error loading graph. Exiting...");
System.exit(1);
}
// -- 2. the visualization --------------------------------------------
// add the graph to the visualization as the data group "graph"
// nodes and edges are accessible as "graph.nodes" and "graph.edges"
Visualization vis = new Visualization();
vis.add("graph", graph);
vis.setInteractive("graph.edges", null, false);
// -- 3. the renderers and renderer factory ---------------------------
// draw the "name" label for NodeItems
LabelRenderer r = new LabelRenderer("name");
r.setRoundedCorner(8, 8); // round the corners
// create a new default renderer factory
// return our name label renderer as the default for all non-EdgeItems
// includes straight line edges for EdgeItems by default
vis.setRendererFactory(new DefaultRendererFactory(r));
// -- 4. the processing actions ---------------------------------------
// create our nominal color palette
// pink for females, baby blue for males
int[] palette = new int[] {
ColorLib.rgb(255,180,180), ColorLib.rgb(190,190,255)
};
// map nominal data values to colors using our provided palette
DataColorAction fill = new DataColorAction("graph.nodes", "gender",
Constants.NOMINAL, VisualItem.FILLCOLOR, palette);
// use black for node text
ColorAction text = new ColorAction("graph.nodes",
VisualItem.TEXTCOLOR, ColorLib.gray(0));
// use light grey for edges
ColorAction edges = new ColorAction("graph.edges",
VisualItem.STROKECOLOR, ColorLib.gray(200));
// create an action list containing all color assignments
ActionList color = new ActionList();
color.add(fill);
color.add(text);
color.add(edges);
// create an action list with an animated layout
ActionList layout = new ActionList(Activity.INFINITY);
layout.add(new ForceDirectedLayout("graph"));
layout.add(new RepaintAction());
// add the actions to the visualization
vis.putAction("color", color);
vis.putAction("layout", layout);
// -- 5. the display and interactive controls -------------------------
Display d = new Display(vis);
d.setSize(720, 500); // set display size
// drag individual items around
d.addControlListener(new DragControl());
// pan with left-click drag on background
d.addControlListener(new PanControl());
// zoom with right-click drag
d.addControlListener(new ZoomControl());
// -- 6. launch the visualization -------------------------------------
// create a new window to hold the visualization
JFrame frame = new JFrame("prefuse example");
// ensure application exits when window is closed
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(d);
frame.pack(); // layout components in window
frame.setVisible(true); // show the window
// assign the colors
vis.run("color");
// start up the animated layout
vis.run("layout");
}
});
}
}
I'm new to Prefuse, but a number of common errors can contribute to the observed problem. Looking at the example,
As discussed here, don't use setSize() on the Display when you really mean to override getPreferredSize().
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
The initial clustering is an artifact of the graph's origin falling on the top-left corner of the Display component at the point (0, 0). Having chosen a preferred size, one can pan() to the center.
private static final int W = 640;
private static final int H = 480;
…
Display d = new Display(vis) {
#Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
};
d.pan(W / 2, H / 2);
Good Evening. I am working on a program thats similar to the old game LiteBrite, where you place colored pegs on a panel and it lights up. In my program, it works similar in that when you click on the panel, it will create a new Ellipse (which ive named ColorEllipse that has specifications for location, size, and color) and that it will store it to be saved. Currently it is as an arraylist but i need it to be in a regular array. I am told the way that would be to make a new array, and copy all the contents of the old array into the new array. Now currently i use an arraylist, but unforutnately this program has specifications where we need to use a regular Array.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class LiteBritePanel extends javax.swing.JPanel{
private final static int OFFSET = 5;
private static int LINE_WIDTH = 2;
private static int CELL_WIDTH = 25;
public ArrayList <Colorable> _circles; // where ColorEllipses will be stored
private ButtonPanel controlpanel; // used to set the color of peg that will be placed
public LiteBritePanel() {
this.setBackground(java.awt.Color.black);
_circles = new ArrayList<Colorable>();
controlpanel = new ButtonPanel(this);
this.addMouseListener(new MyMouseListener(this));
this.add(controlpanel);
}
public void paintComponent(java.awt.Graphics aPaintBrush) {
super.paintComponent(aPaintBrush);
java.awt.Graphics2D pen = (java.awt.Graphics2D) aPaintBrush;
java.awt.Color savedColor = pen.getColor();
pen.setColor(java.awt.Color.black);
for (int ball=0;ball<_circles.size();ball++)
if(_circles.get(ball).isEmpty())
return;
else
_circles.get(ball).fill(pen);
pen.setColor(savedColor);
this.repaint();
}
public void mouseClicked(java.awt.event.MouseEvent e){
boolean foundSquare = false;
for (int ball=0; ball < _circles.size() && !foundSquare; ball++){
if (_circles.get(ball).contains(e.getPoint()) == true){
foundSquare = true;
_circles.remove(ball);
this.repaint();
}
}
}
private class MyMouseListener extends java.awt.event.MouseAdapter {
private LiteBritePanel _this;
public MyMouseListener(LiteBritePanel apanel){
_this = apanel;
}
public void mouseClicked(java.awt.event.MouseEvent e){
_circles.add(new ColorEllipse(controlpanel.getColor(), e.getPoint().x - (e.getPoint().x%CELL_WIDTH), e.getPoint().y - (e.getPoint().y%CELL_WIDTH), CELL_WIDTH-3,_this));
_this.requestFocus();
boolean foundSquare = false;
for (int ball=0; ball < _circles.size() && !foundSquare; ball++){
if (_circles.get(ball).contains(e.getPoint()) == true){
foundSquare = true;
// code for removing ball if one is placed
_this.repaint();
}
}
}
}
}`
Now currently it is set as an Arraylist, but I need it to be in a regular array per this specification. then when the panel is clicked on, it adds a new ColorEllipse into that Array at that specific location (and repaints as necessary for it to show up). A later part of the program would be when i touch a peg thats already placed, it removes it, but thats for another time. right now I need to know how to increment sizes of the array and copy its contents into it. Would anyone be able to tell me what I should change?
To copy arrays, you could use the System.arraycopy(...) method (System API):
public static void arraycopy(
Object src,
int srcPos,
Object dest,
int destPos,
int length)
where you would first create a destination array, perhaps twice as big as the the source array, and pass the old array, the starting index (0), the new array, the destination starting index (0), the length (length of old array), and it should do the rest.
Also you don't want to call repaint inside of paintComponent, trust me. Use a Swing Timer instead. There's a good tutorial on this that Google can help you find.
Depending on how big your board is you can just create an array that has the same size as your board. Alternatively you can do as Hovercraft suggested but it all depends on whether you want to trade cpu for memory.
int MAX_POSSIBLE_ELEMENTS = ...
Colorable[] _circles = new Colorable[MAX_POSSIBLE_ELEMENTS];
....rest of code...
Notice that the maximum number depends on the height and width of the board so you should know this at compiletime.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
For this program I want to implement an array of sorting and searching algorithms. The array will be filled with random numbers. Then I want to draw each array element as a bar (making something like a bar graph). I have a step and run button in the GUI the step is supposed to use selection sort. The problem I am having is: I only know how to do selection sort with a loop. However, I can not use a loop because I have to show the array being sorted step by step. Can anyone show me how to do selection sort without a loop? I will be adding all of the code I have so far because this is my first time posting anything, and I want to make sure I am specific.
ArrayViewer:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.util.Scanner;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ArrayViewer
{
static int[] array;
static int size;
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
//ask for the size of the array until the user enters a size in the right range
do
{
System.out.print("Enter the size of the array (should be between 10 and 80): ");
size=in.nextInt();
}
while (size<10 || size>80);
array= ArrayUtil.randomIntArray(size,100);//create a random array of given size and entries ranging from 0 to 100
final ArrayComponent arrayComp= new ArrayComponent(array); //construct an arrayComponent with the random array
class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//I want the selection sort algorithm to go in here so I can just assign this to my stepButton.
}
}
final JFrame frame=new JFrame("Sorting"); //create and setup the frame
frame.setSize(1200,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonPanel= new JPanel(); // panel to hold the buttons
JPanel panel=new JPanel(new BorderLayout()); // panel to hold the button panel and the array component; uses BorderLayout: read about it in the API
JButton stepButton=new JButton("Step"); //button to go through the algorithm step by step
JButton runButton=new JButton("Run"); //button to run the algorithm
ActionListener listener = new ButtonListener();
stepButton.addActionListener(listener);
buttonPanel.add(stepButton);
buttonPanel.add(runButton);
panel.add(buttonPanel,BorderLayout.PAGE_START); //add the buttonPanel at the top of the panel
panel.add(arrayComp,BorderLayout.CENTER); //add the arraycoponent object in the center of teh panel
frame.add(panel);
frame.setVisible(true);
//print the entries in the array
//System.out.println(arrayComp);
}
}
ArrayComponent:
import javax.swing.JComponent;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.Color;
public class ArrayComponent extends JComponent
{
private int[] theArray;
final int dx=6; //the width of thebars (as well as the with of the spaces between bars)
private int space=0;
int index1 =0;
int index2 =0;
public ArrayComponent(int[] a)
{
theArray=a;
space=600-12*theArray.length/2; //space amount on the horizontal axes to center the graph
//600 is the frame width in the viewer program
//For each bar 12 units on the horixzontal axis is used including the space following it.
//something.addActionListener(new ButtonListener());
}
public void setIndices(int i, int j)
{
index1 = i;
index2= j;
}
public void paintComponent(Graphics g)
{
Graphics2D pen= (Graphics2D) g;
for (int k=0;k<theArray.length;k++)
{
pen.drawRect(space+2*k*dx,5,dx,theArray[k]);
//space: initial space
//2*k*dx: the (horizontal) distance of te kth bar from the start of the graph
//5: bars are located on y=5
//dx: the width of the bars
//theArray[k]: height of the kth bar
}
pen.fillRect(space+2*index1*dx,5,dx,theArray[index1]);
pen.fillRect(space+2*index2*dx,5,dx,theArray[index2]);
}
public String toString()
{
String str=("array=[");
int k=0;
for (k=0;k<theArray.length-1;k++)
str=str+theArray[k]+", ";
str=str+theArray[k]+"]";
return str;
}
}
ArrayUtil(creates the random array):
import java.util.Random;
/**
This class contains utility methods for array manipulation.
*/
public class ArrayUtil
{
private static Random generator = new Random();
/**
Creates an array filled with random values.
#param length the length of the array
#param n the number of possible random values
#return an array filled with length numbers between
0 and n - 1
*/
public static int[] randomIntArray(int length, int n)
{
int[] a = new int[length];
for (int i = 0; i < a.length; i++)
a[i] = generator.nextInt(n);
return a;
}
}
Sorry if the post is lengthy. The program already draws the arrays, it just does not sort them. Thanks for the help.
Let activeIndex refer to the index of the array element to be sorted next (starting with value 0).
Write a method, say stepSelectionSort, which will execute only the one step of selection sort and return. The sorting begins at array[activeIndex].
{5,4,3,2,1} -> activeIndex=0 -> Step.click -> stepSelectionSort() sorts array element at 0 -> {1,4,3,2,5} -> draw() -> activeIndix=1 -> Step.click -> stepSelectionSort() sorts array element 1.
Temporarily write code to do full sort inside a loop
Take all code within the loop and put it in a method
Remove the loop & call the method once each time the user clicks "Step" GUI button
Im creating a program and im stuck at the moment I want the tiles of the droughts board to glow another colour when its highlighted but im not very good with Actionlistners can someone help me out?
I use several class files and here is the code for each.
This is uni work so as I am learning I don't want the code given to me rather a few snippets and helpful advice to go on. the code in the class files is i think uncompilable due to errors because I don't know how to use actionlistners or mouselisteners yet.
To sum up i need an actionlistener for when my mouse hovers over the game board and the tiles change colour.
as I can only post 2 links I will give the 3 shortest class files on here.
EDIT: for ease I have got rid of the links.
EDIT 2: I am also sorry if this seems like a begginer question and well im asking because Im a beginner.
EDIT 3 I have edited the Jframe class to accept mouse listener now I need help changing the color of the tiles, how do i get the color to change from this class file?
EDIT 4 ok i edited the color variable to public i think if thats what you meant, and also I added your code but I dont know which class is my mouselistener and I dont know how to add that color in the way you have laied it out to me.
EDIT 5 ok i tied to make this SSCCE not sure if i was able to do it or not, is this what you meant? if so would it be possible to help me?
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
public class Board extends JPanel
{
private void setupPieces(int numRows)
{
int numPieces = ((numRows * numRows) - (2 * numRows)) / 4;
for (int i = 0; i < numPieces; i++)
{
DraughtsPiece p = new DraughtsPiece(DraughtsPiece.LIGHT_PIECE_COLOUR);
lightPieces.add(p);
p = new DraughtsPiece(DraughtsPiece.DARK_PIECE_COLOUR);
darkPieces.add(p);
DraughtsPiece p = new DraughtsPiece(DraughtsPiece.LIGHT_PIECE_COLOUR);
lightPieces.add(p);
p = new DraughtsPiece(DraughtsPiece.DARK_PIECE_COLOUR);
P.addMouseListener(new <Board.class>);
darkPieces.add(p);
}
public void mouseEntered(MouseEvent m){
((DraughtsPiece) m.getSource()).color=<highlight color goes here>;
}
public void mouseExited(MouseEvent m){
((DraughtsPiece) m.getSource()).color=<normal color goes here>;
}
}
darkPieces.add(p);
}
}
}
For hovering you do not want an ActionListener. ActionListeners are only for clicks on JButton, JMenuItem, etc. If you implement MouseListener then the mouseEntered(MouseEvent) and the mouseExited(MouseEvent) methods will get called whenever the mouse enters or exits one of your pieces.
EDIT: In response to your comments, you can try using this code in your DraughtsBoard.setupPieces method:
EDIT 2: I think you will need a repaint after mouse hovering, but I'm not sure because you removed a lot of your code. I have added code to make the board repaint after a piece color changes.
DraughtsPiece p = new DraughtsPiece(DraughtsPiece.LIGHT_PIECE_COLOUR);
lightPieces.add(p);
p = new DraughtsPiece(DraughtsPiece.DARK_PIECE_COLOUR);
p.addMouseListener(new MouseAdapter(){
public void mouseEntered(MouseEvent m){
((DraughtsPiece) m.getSource()).color=<highlight color goes here>;
DraughtsBoard.this.repaint(); // see my note
}
public void mouseExited(MouseEvent m){
((DraughtsPiece) m.getSource()).color=<normal color goes here>;
DraughtsBoard.this.repaint();
}
});
darkPieces.add(p);
And make DraughtsPiece.color public.
NOTE: You can only use DraughtsBoard.this in an inline class like this one. If you decide not to be lazy and actually have DraughtsPiece implement MouseListener, then you will need some other way to access DraughtsBoard such as a public static variable holding the instance of it
MouseAdapter is an extension of MouseListener which makes all extending classes not have to implement all of the methods from MouseListener. This means I can implement just mouseEntered and mouseExited and leave out the other methods from MouseListener which I don't need.