Solved

Sort Array of Objects

Posted on 2003-10-30
43
585 Views
Last Modified: 2010-03-31
Can some1 give me a quick example of how to use the utils.Arrays.sort on an object. The object extends a JPanel I have a 2 dimensional array of the object, each item has a back ground colour and a value which is of type string the values are "full words" of numbers 1-10.
I need to sort in any order of colour and then of the value of the item.

Think  of the items as a deck of cards ie. the colours representing the suits.

If u can help me with any part of this question i will make more points available for more help.
0
Comment
Question by:sayd
  • 19
  • 16
  • 8
43 Comments
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
0
 

Author Comment

by:sayd
Comment Utility
Here it is can some1 have a look at this and tell me what to add or modify to sort the arrray of tiles player 2 is holding, using util.array.sort.

if u compile and run the 2 files below u will see what im trying 2 do.

DisplayTile1.java
import javax.swing.*;
import java.awt.*;

public class DisplayTile1 extends JPanel implements Comparable{
  private JTextArea tile;

  public DisplayTile1() {
    super(new FlowLayout());
    tile = new JTextArea(3,5);
    tile.setFont(new Font("Arial", Font.BOLD, 10));
    tile.setEditable(false);
    this.add(tile);
  }

  public void setTile(String tileString){
    setBackgroundColor(tileString);
    setText(tileString);
  }

  public void setText(String tileString){
    FontMetrics f = tile.getFontMetrics(tile.getFont());
    String display = ( (tileString.indexOf("-") != -1) ?
                        tileString.substring(0, tileString.indexOf("-")).trim():
                        tileString);
    int leftover = (tile.getWidth() - f.stringWidth(display)) / f.stringWidth(" ");
    for (int k = 0; k < leftover / 2; k++)
      display = " " + display;
    tile.setText("\n" + display);
  }
 
  public void setBackgroundColor(String colourString){
    if (colourString.endsWith("Red")) tile.setBackground(Color.RED);
    else if (colourString.endsWith("Blue")) tile.setBackground(Color.BLUE);
    else if (colourString.endsWith("Yellow")) tile.setBackground(Color.YELLOW);
    else if (colourString.endsWith("Orange")) tile.setBackground(Color.ORANGE);
    else tile.setBackground(Color.WHITE);
  }
}
}

TilingDemo1.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class TilingDemo1 extends JFrame{
  public final static int PLAYERS = 2;
  public final static int TOTAL_TILES = 13;

  private JButton dealTilesButton, mixUpTilesButton;
  private DisplayTile1 displayTiles[][];
  private JLabel status;
  private TilePack myPack;
  private JPanel buttonPanel;
  private JPanel playerPanels[];
  private JPanel playerHandPanels[];
  private JPanel mainPlayPanel;
  private JPanel statusPanel;

  public TilingDemo1(){
    super("Tiles");
    myPack = new TilePack();
    myPack.mixUpTiles();
    buttonPanel = new JPanel(new FlowLayout());
    mainPlayPanel = new JPanel(new GridLayout(PLAYERS,1,10,50));
    playerPanels = new JPanel[PLAYERS];
    playerHandPanels = new JPanel[PLAYERS];
    for (int i = 0; i < PLAYERS; i++) {
      playerPanels[i] = new JPanel(new BorderLayout(5,5));
      playerHandPanels[i] = new JPanel(new GridLayout(1,0,10,10));
      playerPanels[i].add(playerHandPanels[i], BorderLayout.CENTER);
      playerPanels[i].add(new JLabel("Player "+(i+1)), BorderLayout.NORTH);
      mainPlayPanel.add(playerPanels[i]);
    }
    statusPanel = new JPanel(new FlowLayout());
    Container c = getContentPane();
    c.setLayout(new BorderLayout());
    dealTilesButton = new JButton("Deal Tiles");
    dealTilesButton.addActionListener( new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        for (int i = 0; i < PLAYERS; i++) {
          for (int j = 0; j < TOTAL_TILES; j++) {
            Tile dealTilest = myPack.getNextTile();
            if (dealTilest != null) {
              displayTiles[i][j].setTile(dealTilest.toString());
              status.setText("Tile #: " + myPack.getCurrentTileNumber());
            }
            else {
              displayTiles[i][j].setTile("");
              status.setText("Press Mix Tiles Button to continue...");
              dealTilesButton.setEnabled(false);
            }
          }
        }
      }
    }
    );
    buttonPanel.add(dealTilesButton);

    mixUpTilesButton = new JButton("Mix Tiles");
    mixUpTilesButton.addActionListener(
        new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        status.setText("MIXING.....");
        myPack.mixUpTiles();
        status.setText("MIXED");
        dealTilesButton.setEnabled(true);
      }
    }
    );
    buttonPanel.add(mixUpTilesButton);

    displayTiles = new DisplayTile1[PLAYERS][TOTAL_TILES];
    for (int i = 0; i < PLAYERS; i++){
      for (int j = 0; j < TOTAL_TILES; j++) {
        displayTiles[i][j] = new DisplayTile1();
        playerHandPanels[i].add(displayTiles[i][j]);
      }
    }
    status = new JLabel("Hit a button to begin");
    statusPanel.add(status);

    c.add(buttonPanel, BorderLayout.NORTH);
    c.add(mainPlayPanel, BorderLayout.CENTER);
    c.add(statusPanel, BorderLayout.SOUTH);

    pack();
    show(); // show the window

  }

  public static void main(String[] args) {
    TilingDemo1 td1 = new TilingDemo1();

    td1.addWindowListener(
      new WindowAdapter(){
        public void windowClosing(WindowEvent e){
          System.exit(0);
        }
      }
    );
  }
}
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>if u compile and run the 2 files below u will see what im trying 2 do.

Well that's not possible actually, one of the reasons being that there are missing classes.

>>I need to sort in any order of colour and then of the value of the item.

What do you mean by 'any order of colour'? I assume increasing and decreasing?
0
 

Author Comment

by:sayd
Comment Utility
yes i know that i need more classes to sort the tiles i have not been very successful in sorting it so i have rolled it back to the best state before trying to sort anything. I was hoping some1 could show me exactly what i need to do?

and yes i would like to sort it out in any order of colour and then ascending order of number.

I hope you understand what im talking about u should if u compile and run the 2 files.

0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
Sorry.  I missed the fact that you were using straight-forward arrays of tiles.

With the "value of the item", I understand this to be a String containing "One", "Two", "Three", etc.

Is this correct?  Do you want the tiles sorted in this order?

From CEHJ's comment:
>> What do you mean by 'any order of colour'?

I guess that you don't really care which order the colours appear in, only that they are blocked together:

eg. Blue One, Blue Four, Blue Six, Red Two, Red Ten, Green Five etc.

Is that right?
0
 

Author Comment

by:sayd
Comment Utility
Yes thats exactly what i mean preferably with white being the last of the pack if not dont worry about it.

I hope u can help.
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
Can you post TilePack.java please.  I need to know if you have a publicly available array containing the value Strings "One", "Two", etc.
0
 

Author Comment

by:sayd
Comment Utility
i wil send u tilepack.class and tile.class via email to the address on your profile.
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
No!

Don't do that.  It's against EE policy.  If CEHJ (or anyone else) wants to help, they must be allowed full access to all information for the question.
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
I guess that you sent it before you saw my last post.

I'm afraid that I can't use this information, for the reason stated, so I have had to delete the e-mail.

0
 

Author Comment

by:sayd
Comment Utility
OK then I hope this will be enuff info.

public class TilePack {

  // Fields
  public static final String[] TILE_VALUES;
  public static final String[] COLOURS;
  public static int TOTAL_TILES;
  private Tile[] pack;
  private int currentTile;

  // Constructor
  public TilePack() { }

  // Methods
  public void mixUpTiles() { }
  public Tile getNextTile() { return null;}
  public int getCurrentTileNumber() { return 0;}
}
0
 
LVL 15

Assisted Solution

by:jimmack
jimmack earned 150 total points
Comment Utility
Add the following to the attributes of TilingDemo1.java (unless you have something similar in TilePack):

    public final static String[] VALUE_TEXT={"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"};

Then add the following two methods.  I haven't been able to test it, but the principle is sound.

If this doesn't produce the correct results, let us know what is wrong and we can continue from there ;-)

    private int getTextPos(String text)
    {
        int i = 0;
        boolean found = false;
        while ((!found) && (i < 10))
        {
            if (VALUE_TEXT[i].equals(text))
            {
                found = true;
            }
            i++;
        }
       
        return (i);
    }

    private void sortTiles()
    {
        for (int player = 0; player < PLAYERS; player++)
        {
            boolean tilesSwapped = true;
            DisplayTile1 curTile = null;
            while (tilesSwapped)
            {
                tilesSwapped = false;
                for (int tileNum = 0; tileNum < TOTAL_TILES - 1; tileNum++)
                {
                    curTile = displayTiles[player][tileNum];
                    if (curTile.getBackgroundColor() > displayTiles[player][tileNum + 1].getBackgroundColor())
                    {
                        displayTiles[player][tileNum] = displayTiles[player][tileNum + 1];
                        displayTiles[player][tileNum + 1] = curTile;
                        tilesSwapped = true;
                    }
                    else
                    {
                        if (getTextPos(curTile.getText()) > getTextPos(displayTiles[player][tileNum + 1]))
                        {
                            displayTiles[player][tileNum] = displayTiles[player][tileNum + 1];
                            displayTiles[player][tileNum + 1] = curTile;
                            tilesSwapped = true;
                        }
                    }
                }
            }
        }
    }
   
0
 

Author Comment

by:sayd
Comment Utility
2 methods getBackgroundColor and getTextPos should these be new methods created in DisplayTile class


..and cant this sort be done with arrays.util.sort?

thnx
0
 

Author Comment

by:sayd
Comment Utility
is the getBackgroundColor returning awt.color or String because it wont compare between the 2.

the error is: operator > cannot be applied
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
I'm looking into it...
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 350 total points
Comment Utility
You started well declaring that your class implements Comparable. For the generic solution you require (i.e. using the collections classes to sort them) you should do something like the following. Your class should have members 'color' and 'value' too, together with the usual get/set methods:

public final static String[] COLOR_TEXT = { "Red", "Blue", "Yellow", "Orange" };
public final static String[] VALUE_TEXT = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" };


......................................................

public int compareTo(Object other) {
      if (other instance of DisplayTile1) {
            DisplayTile1 otherDisplayTile = (DisplayTile1)other;
            String otherColor = otherDisplayTile.getColor();
            List colors = Arrays.asList(COLOR_TEXT);
            int ixOtherColor = colors.indexOf(otherColor);
            int ixThisColor = colors.indexOf(this.color);
            if (ixThisColor != ixOtherColor) {
                  return ixThisColor - ixOtherColor;
            }
            else {
                  String otherValue = otherDisplayTile.getValue();
                  List values = Arrays.asList(VALUE_TEXT);
                  return values.indexOf(this.value) - values.indexOf(otherValue)
            
            }
            
      }
      else {
            return Integer.MIN_VALUE;// error value
      }
}
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
Sorry this is taking so long, I'm having to create the content in TilePack.java, but I'm nearly there.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>For the generic solution you require

That is,

Arrays.sort(displayTiles)

is all you need to call if you implement the Comparable interface properly
0
 

Author Comment

by:sayd
Comment Utility
CEHJ

 what am i supposed to do with  the line "if (other instance of DisplayTile1) {" sry but i am very weak at this.

thnx again people.
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
That's just a typo.  It should be one word:

if (other instanceof DisplayTile1) {

it checks that the received "other" is an instance of the DisplayTile1 class.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>That's just a typo.  

Yes, sorry missed that. (one word)
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:sayd
Comment Utility
i am getting errors for thest 2 lines  List values = Arrays.asList(VALUE_TEXT);List colors = Arrays.asList(COLOR_TEXT);
 the errors are: reference to list is ambiguous, both class java.util.list in java.util and java .awt .list in java.awt match
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
Change them to:

java.util.List ...
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
This highlights another problem. It's not considered good style to import java.x.* unless not doing so is wildly impracticable. At a brief glance there are not many awt classes, so it would probably be better to do:

import java.awt.GridLayout;

etc.

then your previous problem would dissapear naturally
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
Well it looks like your using CEHJs suggestions (probably a good idea ;-)) with some success.

This seems to have narrowed down your problem(s), so I'm going to stop working on the code I've got at the moment and wait for your next questions.
0
 

Author Comment

by:sayd
Comment Utility
ok now ive added a button called sort to my tilingdemo but i want to only be able to sort 1 players tiles with this button. so for player 2 i would wanna sort all tiles in displayTiles1[1][0 to 12] how do i go about doing that?
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
Are you keeping both players' tiles in the same array?
0
 

Author Comment

by:sayd
Comment Utility
yeah player 1 tiles are in displaytiles[0][0 to 12] and player 2 tiles are indisplayTiles1[1][0 to 12]

im gonna run another question of 800 points of which both of u will get 200 each from if this 1 gets completed ok, so make sure u put a comment on it and the rest of the 400 will be spit depending on who answers.
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
See the comments i put in there
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
This should work with Arrays.sort(displayTiles[playerNum]) shouldn't it?
0
 

Author Comment

by:sayd
Comment Utility
nah it doesnt work it gives a cannot resolve symbol error.
0
 

Author Comment

by:sayd
Comment Utility
actually it compiles ok but produces 101 errors when the button to sort it is pressed
0
 

Author Comment

by:sayd
Comment Utility
ok no errors now but i dont see no changes when i press the button. do i ave to somehow refresh the tiles?
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
Yes.  You've changed the model, but not the display.
0
 

Author Comment

by:sayd
Comment Utility
yeah thnx i think i got it now
0
 

Author Comment

by:sayd
Comment Utility
ok maybe i havent get it any pointers on what i should be writing after its sorted.
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
You need to refresh the content of your playerPanels.
0
 

Author Comment

by:sayd
Comment Utility
can u put up more detail coding if possible?
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
You've already done most of the coding yourself ;-)

    for (int i = 0; i < PLAYERS; i++) {
      playerPanels[i] = new JPanel(new BorderLayout(5,5));
      playerHandPanels[i] = new JPanel(new GridLayout(1,0,10,10));
      playerPanels[i].add(playerHandPanels[i], BorderLayout.CENTER);
      playerPanels[i].add(new JLabel("Player "+(i+1)), BorderLayout.NORTH);
      mainPlayPanel.add(playerPanels[i]);
    }


In this block of code, you create the panels for both players.

You need to adapt this slightly to handle the update.  One way to do this would be to integrate the changes into the discard routine I posted on the other question:

int player = // current player
int curTile = // the tile that is to be discarded

discardedTiles[curDiscTile] = displayTiles[curTile];
curDiscTile++;

playerHandPanels[player].remove(curTile);

while (tileToDiscard < TOTAL_TILES - 1)
{
    displayTiles[curTile] = displayTiles[curTile + 1];
    playerHandPanels[player].add(playerHandPanels[player].getComponentAt(curTile + 1));
    curTile++;
}

displayTiles[curTile] = myPack.getNextTile();
playerHandPanels[player].add(displayTiles[curTile], curTile));


Or something like that ;-)  You'll probably need to play around with it, but that's the general idea.
0
 

Author Comment

by:sayd
Comment Utility
can we forget th other question and can u help me complete this 1 in the easiest method
0
 
LVL 15

Expert Comment

by:jimmack
Comment Utility
I think the two questions are now a bit intermingled ;-)

But I'm always willing to try to resolve an issue.

OK.  Where are we at the moment?

Do you currently have a stable system (ie. does it compile and run OK)?

Have you implemented any sort of mouse event handling?

I *think* that the situation is that you have implemented the sort OK, but this is only on the internal data, not for the displayed Tiles.  Is that right?
0
 

Author Comment

by:sayd
Comment Utility
yes it does compile and run.

no, ive left the mouse listener/event stuff out for the moment.

yes what ive done for now is transferred the tiles, to a new array, then sorted that array, and replaced the original array with the new sorted array, like this:

        player2Hand = new DisplayTile1[TOTAL_TILES];
        System.arraycopy(displayTiles[1], 0, player2Hand, 0, 13);
        Arrays.sort(player2Hand);
        for (int i = 0; i< TOTAL_TILES;i++){
          displayTiles[1][i].setTile(player2Hand[i].getTileData());
        }

So now the sorted tiles are being displayed but they dont seem to be in any sort of order, and some times we get new tiles that werent originally there(before sorting).

I think the sorting bit isnt working, any ideas on  a fix? or am i doing summet else wrong?
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
This seems partly wrong to me.

a. you copy the array but  don't do a deep copy. So when you call
>>Arrays.sort(player2Hand);
you're effectively sorting the original array
b. the loop that gets executed after that contains a redundant statement - the two arrays are effectively already identical.

As i said before, you will probably find it more logical to provide separate containers for each player's tiles and use a collection instead of an array.

>>I think the sorting bit isnt working

If you're using the code i posted earlier, i can't see any problem with it.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now