2011-08-24 8 views
5

Staram się komfortowo z JTables, TableModels, JTableHeaders, renderujących itd Próbuję zrobić prosty atrapę tabeli (dla celów praktycznych), które wygląda następująco:Zmiana Swing JTable komórkowe Kolory

- 1 2 3 
A A1 A2 A3 
B B1 B2 B3 
C C1 C2 C3 

Chcę również, aby komórka B2 - i tylko ta komórka - miała niebieskie tło (Color.BLUE) - wszystkie pozostałe komórki mogą mieć domyślny kolor Swinga, do którego są przypisane automagicznie.

Mój kod znajduje się poniżej i jest oparty na niezliczonych przykładach, które znalazłem na tej stronie oraz w Internecie. Ale nie osiągam pożądanych rezultatów. Zamiast tego otrzymuję tabelę wyglądającą tak:

A A1 A2 A3 
B B1 B2 B3 
C C1 C2 C3 

Zauważ, że pierwszego wiersza (nagłówka) w ogóle nie ma. Dodatkowo, z poniższym kodem I, to wykonuje i ustawia kolor komórek, które mają kolor, a nie tylko komórkę B2, którą chcę.

Kod:

public class MyTable 
{ 
    public static void main(String[] args) 
    { 
     String[][] data = getTableData(); 
     String[] cols = getTableCols(); 

     JFrame frame = magicallyCreateJFrame();  // I promise this works! 
     MyRenderer myRenderer = new MyRenderer(); // See below 

     DefaultTableModel defModel = new DefaultTableModel(data, cols); 
     JTable myTable = new JTable(defModel); 

     myTable.setDefaultRenderer(Object.class, myRenderer); 

     frame.add(myTable); 
     frame.pack(); 
     frame.setVisible(true);    
    } 
} 

public static String[] getTableCols() 
{ 
    String cols = 
    { 
     "-", 
     "1", 
     "2", 
     "3", 
    }; 
} 

public static String[][] getTableData() 
{ 
    String[][] data = 
    { 
     { 
      "A", 
      "A1", 
      "A2", 
      "A3", 
     }, 
     { 
      "B", 
      "B1", 
      "B2", 
      "B3", 
     }, 
     { 
      "C", 
      "C1", 
      "C2", 
      "C3", 
     }, 
    }; 

    return data; 
} 

A quick-n-brudne MyRenderer klasa:

public class MyRenderer extends DefaultTableCellRenderer 
{ 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
{ 
    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

    if(row == 2 && column == 2) 
     c.setBackground(new java.awt.Color(0, 0, 255)); 

    return c; 
} 

} 

Poza tym, że jest to straszne kod i łamie wiele „najlepszy ćwiczy "typowe wzorce i techniki (pamiętaj, że to jest po prostu coś, z czym się bawię), czy jest coś, co tutaj robię, to jest rażąco oczywiste? Dlaczego nie otrzymuję nagłówka tabeli (pierwszy wiersz "- 1 2 3")? Dlaczego mój domyślny mechanizm renderujący komórki nie działa w konkretnej komórce B2, którą określam?

JTables to dziwne, piękne i potężne bestie. Powoli otulam się moimi myślami, ale dławię się przy implementacji. Dzięki wszystkim, którzy mogą pomóc!

+0

Nadal czekam na SSCCE ... – camickr

+0

Zobacz także ten powiązany [przykład] (http://stackoverflow.com/a/12352838/230513). – trashgod

Odpowiedz

14

Musisz upewnić się zresetować renderujący do swojego domyślnego koloru tła (i uchwyt wybór wierszy):

if (! table.isRowSelected(row)) 
{ 
    if(row == 2 && column == 2) 
     c.setBackground(new java.awt.Color(0, 0, 255)); 
    else 
     c.setBackground(table.getBackground()); 
} 

W przyszłości zakładać właściwą SSCCE ze swoim pytaniem.

3

Gdzie podajesz renderer do koloru B2 i tylko B2? Być może chcesz umieścić blok if w metodzie getTableCellRendererComponent tak, aby kolor tła był ustawiony na niebieski tylko wtedy, gdy wartość obiektu wartości JTable toString() to "B2" lub jeśli wartości wiersza i kolumny odpowiadają komórce B2.

Aby wyświetlić nagłówek tabeli, należy najpierw dodać tabelę do JScrollPane, a następnie dodać JScrollPane do elementu nadrzędnego.

Najważniejsze: przeczytaj samouczki Swing na temat JTables, ponieważ wszystko jest tam wyjaśnione.

+0

Dzięki Hovercraft - proszę odwołać się do dodanego warunku w klasie Renderer. Nadal nie działa - czego mi brakuje? – IAmYourFaja

4

Half-odpowiedź:

Trzeba umieścić swój JTable Wewnątrz JScrollPane mieć nagłówek wyświetlany. Lub alternatywnie możesz ręcznie dodać do układu komponent zwrócony przez myTable.getTableHeader(). Polecam jednak używanie JScrollPane.

EDIT:

Jak sugeruje poniżej, aby włączyć niebieskim tle tylko dla jednego konkretnego ogniwa, wszystko co musisz zrobić, to dodać test jak ten:

if(column == 2 && row == 1) { 
    c.setBackground(Color.BLUE); 
} else { 
    c.setBackground(Color.WHITE); 
} 
+0

I: co się stanie, jeśli w 'myTable.setDefaultRenderer (Object.class, myRenderer);' zamienisz 'Object.class' na' String.class'? – ChrisJ

+0

jak to ma pomóc jego problemowi? –

+0

Wszystkie dane w mojej tabeli będą ciągami. Czy muszę zmienić to wywołanie zamiast używać String.class, a jeśli tak, to czy coś to zepsuje? Co powinienem zmienić, aby naprawić taką przerwę? – IAmYourFaja

0

Może myTable.setDefaultRenderer(String.class, myRenderer); działa poprawnie.

0

Uważam, że prawidłowym sposobem kolorowania stołu jest użycie ColorHighlighter. Podałem example here.

Powiązane problemy