This is a bit embarrassing. I have a compareTo function that I intend to use on a JButton, so when the user presses it they can see which is the highest ranked object. I already have a Listener class for the JButton but I don't know how to make the Listener use the compareTo function because it needs two parameters.
This is my compareTo function:
public int compareTo(Film film1, Film film2) {
if (film1.getFinalScore() < film2.getFinalScore()) return -1;
if (film1.getFinalScore() > film2.getFinalScore()) return 1;
return 0;
}
And this is the actionPerformed function in the Listener class:
#Override
public void actionPerformed(ActionEvent e) {
this.cm.compareTo(null, null);
}
The Auto-correct suggested to put the parameters to null to make it work, but it's obviously never as simple as the Auto-Correct suggests.
So, how can I make the Listener perform the compareTo function using all of my objects to list them from highest to lowest?
Thanks in advance!
As you need to compare 2 Films together you can do that in Film Class by implementing Comparable<Film> then implementing the compareTo method in the class.
After That , Hold your films in any collection as ArrayList then simply call Collections.max(films) to get the max film object in the list.
Here is the a Film class for demonstration:
public class Film implements Comparable<Film>{
int finalScore ;
public Film(int finalScore){
this.finalScore = finalScore;
}
public int getFinalScore(){
return this.finalScore;
}
#Override
public int compareTo(Film film2) {
if (this.getFinalScore() < film2.getFinalScore()) return -1;
if (this.getFinalScore() > film2.getFinalScore()) return 1;
return 0;
}
}
And this is the main :
public static void main(String[] args) {
ArrayList<Film> films = new ArrayList<>();
films.add(new Film(100));
films.add(new Film(400));
films.add(new Film(200));
films.add(new Film(300));
System.out.println(Collections.max(films).getFinalScore());//prints 400
}
So your actionPerformed will be like this
#Override
public void actionPerformed(ActionEvent e) {
Film maxFilm = Collections.max(films);
//then use maxFilm object to do anything you need
}
Related
I have this Array.sort method in one class to list my objects from highest to lowest:
public static void sortFilm(Film[] array) {
Arrays.sort(array, new Comparator<Film>() {
#Override
public int compare(Film f1, Film f2) {
return Double.compare(f1.getFinalScore(), f2.getFinalScore());
}
});
printArr(array);
}
I intend to use it inside an actionPerformed for my listener class but I don't know how to create the necessary parameter (Film[]) to make use of the Array.sort method. My intention is to show a list of all objects from highest to lowest once the specific button is pressed.
Thanks in advance!
edit:
This is how I think it will sort of look like:
#Override
public void actionPerformed(ActionEvent e) {
this.cm.sortFilm(?);
}
Question mark is the missing parameter.
As you need to sort Film objects together you need a compareTo function to compare each 2 Films together, you can do that in Film Class by implementing Comparable<Film> then implementing the compareTo method in the class.
After That , Hold your films in any collection as ArrayList instead of array then simply call Collections.sort(films) to get your films list in increasing or decreasing order .
Here is the a Film class for demonstration:
public class Film implements Comparable<Film>{
int finalScore ;
public Film(int finalScore){
this.finalScore = finalScore;
}
public int getFinalScore(){
return this.finalScore;
}
#Override
public int compareTo(Film film2) {
return Double.compare(this.finalScore, film2.finalScore);
}
}
And this is the main :
public static void main(String[] args) {
ArrayList<Film> films = new ArrayList<>();
films.add(new Film(100));
films.add(new Film(400));
films.add(new Film(200));
films.add(new Film(300));
/*reverse order is the reversed order of your compareTo method
, as you need Decreasing manner and the compareTo method
outputs the Increasing manner then you need to reverse it,
remove this comparator if you need it increasing.*/
Collections.sort(films,Comparator.reverseOrder());
for (Film film : films) {
System.out.print(film.finalScore+" "); // prints 400 300 200 100
}
}
So your actionPerformed will be like this
#Override
public void actionPerformed(ActionEvent e) {
Collections.sort(films,Comparator.reverseOrder());
//now films are sorted! use films objects to do anything you need
}
I got a class used in an Android app, which is declared like this:
public static class MyData implements Comparable<MyData>
{
public MyEnum myEnum;
#Override
public int compareTo(MyData another)
{
if(this.myEnum.equals(MyEnum.Value1))
{
return 1;
}
if(another.myEnum.equals(MyEnum.Value1))
{
return -1;
}
if(this.myEnum.equals(MyEnum.Value2))
{
return 1;
}
if(another.myEnum.equals(MyEnum.Value2))
{
return -1;
}
return 0;
}
}
I defined a list: List<MyData> myList = new LinkedList<MyData>();
After adding items to the list I call: Collections.sort(myList)
The problem is that when I debug, I see the compareTo method being called after the sort method is invoked, however it doesn't enter the first if even that it should. I even put the Boolean expression in Eclipse in the "Expressions" view and it returned true, but the code simply jumps to the return 0; and the list is not being sorted like I want to.
Why is that?
Eventually I changed that enum class member to an int member which was initialized with the ordinal value inside the Enum.
Then the compareTo method was changed like this:
#Override
public int compareTo(MyData another)
{
Integer myVal = this.intVal;
Integer otherVal = another.intVal;
return myVal.compareTo(otherVal);
}
we are working on a project trying to make a message in a JOptionPane show up when a button is pressed and certain conditions are met. However whenever the code is activated and a button is pressed, the JOptionPane shows up with no message. Here is the code that creates the GUI
package BlackJack;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class BlckJckUI {
public static void main(String[] args) {
JFrame GUI = new JFrame("Blackjack Advisor");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(1000,900);
GUI.setVisible(true);
JButton two = new JButton(Two);
two.setSize(300, 100);
two.setLocation(100, 200);
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
});
GUI.add(two);
This is the code that works out the logic.
package BlackJack;
public class Math {
public int cardvalue;
public Math()
{
Arrays array = new Arrays();
if (array.clicktracker == 1)
{
array.dealer = cardvalue;
array.result = "Please select the first card you have :)";
}
else if (array.clicktracker == 2)
{
array.playerhand.add(cardvalue);
array.result = "Please select the second card you have :)";
}
else if (array.clicktracker >= 3)
{
array.playerhand.add(cardvalue);
if (array.playerhandtotal <= 8)
{
// array.result = result statement
array.result = "You should just hit until you're safe. If the dealer 6 or below,\n"
+ " the chances are that he'll bust and if not, remain low above 17.\n"
+ " As long as you can pull a 17 or higher, you should be safe. Pick \n"
+ "another card or reset.";
This is the code that creates the Array and variables associated with it.
package BlackJack;
import java.util.ArrayList;
public class Arrays{
public String result = null;
ArrayList<Integer> playerhand = new ArrayList<Integer>();
public int dealer = 0;
public int clicktracker = 0;
public int playerhandtotal = 0;
{
for (int element: playerhand)
{
playerhandtotal = element + playerhandtotal;
}
System.out.println(result);
System.out.println(dealer);
System.out.println(clicktracker);
}
}
In your Math constructor, you are changing the result of a different type of array.result than the one you are trying to display.
I would consider passing the Arrays instance into the Math constructor so that you can modify the result from there. Be sure to not reassign the instance though.
public void actionPerformed(ActionEvent e)
{
Arrays array = new Arrays();
Math math = new Math(array);
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
}
...
public Math(Arrays array)
{
if (array.clicktracker == 1)
{
// And so on ...
The problem is that you are creating two separate instances of your Arrays class. Once in the actionPerformed method and also within the constructor of your Math class.
This code you currently have:
Arrays array = new Arrays();
Math math = new Math();
math.cardvalue = 2;
array.clicktracker++;
JOptionPane.showMessageDialog(null,array.result);
will display the result of the Arrays object you created in the actionPerformed method - which is null as the result of this object is initialised to null and never set.
This has been mentioned in other answers and comments and will solve it from producing null but this approach will now always yield the same result as you are still always creating a new instance of your Arrays class in your actionPerformed method.
A better approach would be to separate the logic of the result from the constructor of your Math class into another method and create this instance of your Math class outside of the actionPerformed method. Then within your actionPerformed method call your method which will do the logic for your result.
In UI:
Math math = new Math();
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
math.cardvalue = 2;
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
In Math:
public class Math {
public int cardvalue;
public Arrays array;
public Math()
{
array = new Arrays();
}
public void calcResult(){
if (array.clicktracker == 1)
{
//...rest of your logic
}
}
I am having this issue where I have a PiorityBlockingQueue to sort the items in it. The are several options the user can sort the items being added into the queue.
The one I'm stuck at is trying to order the queue by the most occurences of an Item.
The choice of the comparison is determined in the constructor of MyQueue. But the counts of (eg. Low, Medium, High) isnt determined until later. When it is determined, I wanted to call the update(String lst) method from ItemComparator to update the hashmap so that the sorting is correct.
So my issue is I can't call that method. I know I'm missing something but I can't figure it out. Any help? Maybe there a better design than what I doing now?
public class ItemComparator implements Comparator<Item>
{
public void update(String lst){
test = lst;
}
public int compare(Item o1, Item o2) {
HashMap<String,Integer> priority = new HashMap<>();
priority.put("LOW", 1);
priority.put("MEDIUM", 2);
priority.put("HIGH", 3);
if (priority.get(o1.getPriority()) > priority.get(o2.getPriority())) {
return -1;
}
if (priority.get(o1.getPriority()) < priority.get(o2.getPriority())) {
return 1;
}
return 0;
}
}
This statement wont work from this class comparator.update(aString);
public class MyQueue implements AQueue{
private Comparator<Ticket> comparator;
private PriorityBlockingQueue<Ticket> listOfTickets;
private String policy;
BlockingQImpl(String processingPolicy) throws InvalidDataException {
setPolicy(processingPolicy.toUpperCase());
setComparator(policy);
}
private void setComparator(String policy) throws InvalidDataException {
if (policy.equals("THIS")) {
comparator = new ItemComparator(countString);
}
listOfTickets = new PriorityBlockingQueue<>(10, comparator);
}
public void addList(int id) {
ticks.add(id)
comparator.update(aString);
}
}
I think your problem is the compilation error at comparator.update(aString); right?
It is because you have declared comparator as Comparator<Ticket>, that means, you are "seeing" it as a Comparator, and in a Comparator, there is no update() method.
You should declare it as ItemComparator
i.e.
private ItemComparator comparator;
I'm trying to make a class implement an interface correctly but seem to have hit a brick wall. I am not sure if the code I have already written is correct but it was the only way I understood how to approach the task. I have been given an interface with this information:
package mvcchords;
public interface NoteStore {
int getNextNote();
boolean hasNextNote();
void noteAdded(int midicode);
void start(int sortOrder);
}
The application displays piano keys which allow the user to click on them, and it saves the order they were clicked and the midicode of the notes for the specific sound. Then when the user clicks play, it recalls the tune in the order the notes were saved. When a user clicks on a note noteAdded is called. hasNextNote is used to check if it is the end of the saved notes or not. getNextNote is used to get the next note from the array list and start is called when the user clicks the play button. I have been told the integer sortOrder is irrelevant for this part of the task. I have been told that when the play button is clicked it should call the start method and then repeatedly call the getNextNote method until all the notes have been retrieved.
Below is the code I have written so far for a class to implement this interface;
import java.util.*;
import mvcchords.*;
public class MyNoteStore implements NoteStore {
public ArrayList<Integer> Notes;
public void noteAdded(int midicode) {
Notes.add(midicode);
}
public boolean hasNextNote(int k) {
if(Notes.get(k) != null)
return true;
else
return false;
}
public int getNextNote(int k) {
if(hasNextNote(Notes.get(k)) == true)
return Notes.get(k);
else
return 0;
}
public void start(int sortOrder) {
for(int k = 0; k < Notes.size(); k++){
hasNextNote(k);
getNextNote(k);
}
}
}
This code gives me an error saying
MyNoteStore is not abstract and does not override abstract method `hasNextNote()` in `mvcchords.NoteStore`.
I don't know where to go from here and any help would be appreciated. If further information is needed then I will do my best to clarify any points I have made.
Thank you in advance :)
While you have created methods with the correct names you need to have the correct parameters and return types as well. So in this case you need to alter:
int getNextNote(int i);
boolean hasNextNote(int k);
to remove the integer parameters.
Basically you need to keep track of the notes played back so far in the class so that you don't need to pass an integer about all the time. You could either use an Iterator or just store a integer to track the last index played. The below method uses an iterator, maybe you should try and create the one with an integer yourself.
public class MyNoteStore implements NoteStore {
ArrayList<Integer> notes = new ArrayList<Integer>();
Iterator<Integer> playbackIter;
public void noteAdded(int midicode) {
notes.add(midicode);
}
public boolean hasNextNote() {
if (playbackIter != null) {
return playbackIter.hasNext();
}
else {
return false;
}
}
public int getNextNote() {
if (playBackIter != null) {
return playBackIter.next();
}
else {
return -1;
}
}
public void start(int sortOrder) {
playBackIter = notes.iterator();
while(hasNextNote()) {
int note = getNextNote();
//play note
}
}
}
The parameters in the method are different between your implementation and the declaration in the interface.
Well,
your interface defines the methods:
int getNextNote();
boolean hasNextNote();
void noteAdded(int midicode);
void start(int sortOrder);
So,
your class has to implement them with the exact definition, which means with the same return type AND parameters. So you can either change them in the interface declaration or in the class implementation.