Sort Array of Objects

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.
saydAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jimmackCommented:
0
saydAuthor Commented:
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
CEHJCommented:
>>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
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

saydAuthor Commented:
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
jimmackCommented:
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
saydAuthor Commented:
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
jimmackCommented:
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
saydAuthor Commented:
i wil send u tilepack.class and tile.class via email to the address on your profile.
0
jimmackCommented:
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
jimmackCommented:
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
saydAuthor Commented:
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
jimmackCommented:
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
saydAuthor Commented:
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
saydAuthor Commented:
is the getBackgroundColor returning awt.color or String because it wont compare between the 2.

the error is: operator > cannot be applied
0
jimmackCommented:
I'm looking into it...
0
CEHJCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jimmackCommented:
Sorry this is taking so long, I'm having to create the content in TilePack.java, but I'm nearly there.
0
CEHJCommented:
>>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
saydAuthor Commented:
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
jimmackCommented:
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
CEHJCommented:
>>That's just a typo.  

Yes, sorry missed that. (one word)
0
saydAuthor Commented:
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
jimmackCommented:
Change them to:

java.util.List ...
0
CEHJCommented:
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
jimmackCommented:
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
saydAuthor Commented:
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
CEHJCommented:
Are you keeping both players' tiles in the same array?
0
saydAuthor Commented:
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
CEHJCommented:
See the comments i put in there
0
jimmackCommented:
This should work with Arrays.sort(displayTiles[playerNum]) shouldn't it?
0
saydAuthor Commented:
nah it doesnt work it gives a cannot resolve symbol error.
0
saydAuthor Commented:
actually it compiles ok but produces 101 errors when the button to sort it is pressed
0
saydAuthor Commented:
ok no errors now but i dont see no changes when i press the button. do i ave to somehow refresh the tiles?
0
jimmackCommented:
Yes.  You've changed the model, but not the display.
0
saydAuthor Commented:
yeah thnx i think i got it now
0
saydAuthor Commented:
ok maybe i havent get it any pointers on what i should be writing after its sorted.
0
jimmackCommented:
You need to refresh the content of your playerPanels.
0
saydAuthor Commented:
can u put up more detail coding if possible?
0
jimmackCommented:
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
saydAuthor Commented:
can we forget th other question and can u help me complete this 1 in the easiest method
0
jimmackCommented:
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
saydAuthor Commented:
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
CEHJCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.