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
Related
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 ?
I am trying to learn some basic java by following a book, one of the exercises requires that I display a set of bar graphics based on user input.
I have to query the user to input the no. of bars to be shown and the length of each.
I use the following:
1`st is the Bar class I defined to draw rectangles corresponding to the numbers inputed
import java.awt.Graphics;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Bar extends JPanel
{
private int noOfBars; // number of bars to display
int i = 0;
// constructor with choice input
public Bar (int noOfBars)
{
this.noOfBars = noOfBars;
}
// draw desired shapes starting from default position (0, 5) and incrementing for each new bar
public void paintComponent(Graphics g)
{
super.paintComponent(g);
do
{
String input = JOptionPane.showInputDialog("Enter number: ");
int length = Integer.parseInt(input);
for (int j = 1; j <= length; j++)
g.drawRect(0, 5 + i * 20 ,j * 15 , 15);
i++;
} while (i < noOfBars);
}
}
2`nd is the main class:
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class ShapesExercise
{
public static void main(String[] args)
{
int noOfBars = 0;
// obtain user choice
String input = JOptionPane.showInputDialog("Enter total bars to display:");
noOfBars = Integer.parseInt(input);
if (noOfBars == 0)
{
JOptionPane.showMessageDialog(null,"Invalid number.");
input = JOptionPane.showInputDialog("Enter total bars to display::");
noOfBars = Integer.parseInt(input);
}
JFrame application = new JFrame();
application.setSize(300, 40 + 25 * noOfBars);
Bar panel = new Bar(noOfBars);
application.add(panel);
application.setVisible(true);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
My issue is as follows:
The first message_dialog (the one created in the main class) works correctly, popping up only once and querying for input.
But the message_dialogs generated by the Bar class keep popping up even after reaching the end of the "do while" loop (this was initially a "for" loop but I changed it to "do while" in an attempt to troubleshoot the code).
I have no idea why this happens. While researching online I could not find something related.
Thank you in advance.
paintComponent is called by Swing’s painting architecture, which in turn is largely dependent on the native system. paintComponent can be called several times per second, depending on the circumstances; it may be called once, or several times, when a window is moved or brought to the front. It may be called for each movement of the mouse over it.
You have no control over when paintComponent is called. You must only draw in that method. You MUST NOT call JOptionPane in it. You must not change any state, and you must not change the component or any other components in that method.
If you want to call JOptionPane, do it elsewhere, and then call repaint() to request that the Swing system eventually call your paintComponent method.
You can learn more at https://docs.oracle.com/javase/tutorial/uiswing/painting/.
I was learning about arrays today in school, and I am trying to do this problem, but cannot figure it
// Fortune Teller
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
public class FortuneTeller extends JFrame
implements ActionListener
{
private static final EasySound ding = new EasySound("ding.wav");
// Declare an array of "fortunes" (strings):
___________________________________________
...
private JTextField display;
public FortuneTeller()
{
super("Fortune Teller");
display = new JTextField(" Press \"Next\" to see your fortune...", 25);
display.setBackground(Color.WHITE);
display.setEditable(false);
JButton go = new JButton("Next");
go.addActionListener(this);
Container c = getContentPane();
c.setLayout(new FlowLayout());
c.add(display);
c.add(go);
}
public void actionPerformed(ActionEvent e)
{
// Pick and display a random fortune:
___________________________________________
...
display.setText(" " + __________________ );
ding.play();
}
public static void main(String[] args)
{
JFrame window = new FortuneTeller();
window.setBounds(300, 300, 300, 100);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setVisible(true);
}
}
I am trying to fill in the blanks.
For the first one,, would it just be just be String [] Fortune;?
But how would I end up initializing it?
And then for the second part, what would I have to do?
Please help as I am extremely lost.
Here are some hints to help you (without actually doing your homework for you).
You can create and populate an array of strings in one line using the following syntax:
String[] colours = {"Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet"};
You can generate a random number between zero and x (inclusive) using the following syntax:
int randomNumber = Math.random() * (x + 1);
You can select a random string from an array with the following syntax:
String randomColour = colours[Math.random() * colours.length];
As found by the simple Google search "How to declare an array in Java":
String[] fortune = {"You're going to be right","You're going to die","You're going to find a cat"};
This also initializes the array.
Then to get the an element of the array, you do:
fortune[1];
//Returns: You're going to die
For this though, I'd do a random number generator to pick a number between 0 and the length of the array:
int value = Math.random() * fortune.length;
fortune[value];
I am creating a java GUI which is a fortune teller. The GUI will spit out one of twelve fortunes every time you click the "get my fortune" button, the strings will never repeat back to back, can can repeat later after other strings have gone before it. I have made already for the most part. But now I am having some trouble creating the while loops to display the strings without repeating. I have looked at my book which didn't really help. If you guys could point me in the right direction,it would be much appreciated. Thanks!
I entered all of the code so you can see the variables used. But my question starts at class RndButtonListener.
package FortuneTellerRunner;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
*
* #author a3cal_000
*/
class FortuneTellerFrame extends JFrame
{
final private JPanel mainPnl, titlePnl, displayPnl, buttonPnl, imagePnl;
final private JButton quitBtn, rndBtn;
final private JLabel titleLbl, iconLbl;
final private JTextArea displayTa;
final private JScrollPane scroller;
public String[] fortune = new String [12];
int newIndex, oldIndex;
private static final int HEIGHT = 250;
private static final int WIDTH = 450;
public FortuneTellerFrame()
{
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPnl = new JPanel();
mainPnl.setLayout(new BorderLayout());
displayPnl = new JPanel();
buttonPnl = new JPanel();
titlePnl = new JPanel();
ImageIcon icon = new ImageIcon("FortuneTellerIcon.JPEG");
iconLbl = new JLabel(icon);
titleLbl = new JLabel("Fortune Teller!");
displayTa = new JTextArea();
imagePnl = new JPanel();
scroller = new JScrollPane();
// Create the layout of the title panel
titlePnl.setLayout(new GridLayout(2,1));
add(mainPnl);
// Set the label to the panel.
titlePnl.add(titleLbl);
titlePnl.add(iconLbl);
// add the panel to the main panel.
mainPnl.add(titlePnl, BorderLayout.NORTH);
mainPnl.add(scroller, BorderLayout.CENTER);
mainPnl.add(displayTa, BorderLayout.CENTER);
// Create the "Get my fortune button.
rndBtn = new JButton("Get My Fortune!");
quitBtn = new JButton("Quit");
// Add the buttons to the buttonPnl in grid layout.
buttonPnl.add(rndBtn);
buttonPnl.add(quitBtn);
// Create the grid layout for the button panel.
buttonPnl.setLayout( new GridLayout(1, 2));
// Add the button panel to the grid layout, South.
mainPnl.add(buttonPnl, BorderLayout.SOUTH);
ActionListener listener = new RndButtonListener();
rndBtn.addActionListener(listener);
quitBtn.addActionListener(listener);
}
class RndButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
fortune[0] = "He who throws dirt is losing ground.";
fortune[1] = "You will find the love of your life in food.";
fortune[2] = "Do or do not, there is no try.";
fortune[3] = "Tomorrow is a better day to try anything of importance.";
fortune[4] = "Life's not about how hard you can hit, but how hard you can get hit and keep moving forward.";
fortune[5] = "You can't be late until you show up.";
fortune[6] = "If you think things can't get worse it's probably only because you lack sufficent imagination.";
fortune[7] = "If youre at the top it means you have further to fall.";
fortune[8] = "Even in last place, youre still in the race.";
fortune[9] = "The road to riches is paved on the failures of others.";
fortune[10] = "If you feel like your going no where, get off the treadmill.";
fortune[11] = "Thinking about going to the gym is just as good as going.";
Random rnd = new Random(fortune.length);
do
{
newIndex = rnd.nextInt(fortune.length);
}
while(newIndex == oldIndex);
do
{
System.out.println(fortune[newIndex]);
displayTa.append(fortune[newIndex] + "||");
displayTa.updateUI();
mainPnl.updateUI();
oldIndex = newIndex;
}
while(newIndex != oldIndex);
class QuitButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
System.exit(0);
}
}
}
}
}
The basic problem is you are re-creating the Random with the same seed each time, which is generally creating the same random sequence over and over again.
Instead try using...
do {
newIndex = (int) Math.round(Math.random() * (fortune.length - 1));
} while (newIndex == oldIndex);
You also don't need the second loop, it's just clutter that confuses the situation.
You may also find that...
displayTa.append(fortune[newIndex] + "\n");
produces nicer output (IMHO)
You may also wish to take a look at How to use Scroll Panes
Your program run fine, but this is a problem, fortune.length is a random seed which return me only 6 and 8 when I later called Random.nextInt().
Random rnd = new Random(fortune.length);
Do it this way
Random rnd = new Random();
and also consider the formatting solution given by MadProgrammer.
Random() gives you same number pattern. Try Random(System.currentTimeMillis()). It uses current time as seed, so you can get real random numbers.
I did something similar to this just today, so let's see if I can remember... I made an ArrayList of type int of how many items I had (fortunes)
ArrayList<Integer> fortuneSeq = new ArrayList<Integer>();
Then add in some numbers starting from 0 to code for the fortunes.
for(int i = 0; i < fortune.length; i++) {
fortuneSeq.add(i);
}
Then I used the shuffle() method from the Collections class to randomize the list.
Collections.shuffle(fortuneSeq);
After that, just loop through to access the fortunes.
for(int i = 0; i < fortune.length; i++) {
System.out.println(fortune[fortuneSeq.get(i)]);
//...
}
Edit: Silly autocorrect, you don't like programmers.
Edit: Fixed some furtunes instead of fortunes and fixed println statement.
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.