Portál AbcLinuxu, 12. ledna 2026 08:18
final class DateTableRenderer extends DefaultTableCellRenderer
{
DateFormat m_formatter;
public DateTableRenderer() {
super();
m_formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
}
@Override
public void setValue(Object value) {
setText((value == null) ? "" : m_formatter.format(value));
}
}
Problém však je, že takto renderovaná buňka nerespektuje look&feel, viz obrázek (modrá tečka je řádek, který má focus, červená znázorňuje pozici kurzoru). Zkoušel jsem setOpacity() a to nemá na výsledek vliv. Otázkou tedy je, jak to správně napsat, aby to vypadalo "hezky".
Řešení dotazu:
setValue() jsem snad ještě neviděl… U rendereru je hlavně důležitý způsob jeho použití, chtělo by vidět kód, kterým ho nastavujete do tabulky. Kžadopádně bych v setValue() nevolal setText(), ale super.setValue().
JTable.setDefaultRenderer(Date.class, new DateTableRenderer());. Můj model pro ten column vrací právě Date.class (metoda getColumnClass(int)).
setText((value == null) ? "" : value.toString());
org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRenderer$DateRenderer. Jenže to mi není moc platný, když potřebuju, aby se to renderovalo správně pro každý nastavený UI Look&Feel, pouze potřebuju změnit text. Když zase budu v modelu vracet přímo text a né datum, tak mi zase bude špatně fungovat řazení data a budu muset předělávat to
final class DateTableRenderer implements TableCellRenderer
{
DateFormat m_formatter;
TableCellRenderer m_stringRenderer;
public DateTableRenderer(TableCellRenderer stringRenderer) {
super();
m_formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
m_stringRenderer = stringRenderer;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value == null) {
return null;
}
else {
String str = m_formatter.format((Date)value);
return m_stringRenderer.getTableCellRendererComponent(table, str, isSelected, hasFocus, row, column);
}
}
}
Nastavím ho takto: setDefaultRenderer(Date.class, new DateTableRenderer(getDefaultRenderer(String.class)));. Výsledek je trochu jiný, ale pořád špatný. Jestli implementuju přímo TableCellRenderer nebo podědím z DefaultTableRenderer a překryju tu metodu nemá žádný vliv ...
getDefaultRenderer(String.class) ten správný renderer (tj. ten z vámi použitého L&F)? Pokud ano, pak už mne napadá jedině možnost, že ten L&F ten renderer nějak částečně obchází, nebo že si tam někde zjišťuje typ rendereru, a pokud je nastaven ten „vlastní“ renderer, chová se to k němu nějak jinak. Chtělo by to podívat se na implementace toho rendereru a TableUI v tom L&F.
final class DateTableRenderer extends org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRenderer
{
DateFormat m_formatter;
public DateTableRenderer() {
super();
m_formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
}
@Override
public void setValue(Object value) {
setText(value == null ? "" : m_formatter.format((Date)value));
}
}
Výše napsaný renderer funguje správně. Akorát jsem teď omezený na Substance L&F. Já jsem s ním spokojený, ale jinému uživateli se třeba líbit nemusí. Ještě kouknu na zdroják substance L&F, jak to kreslí, jestli by to šlo nějak lépe.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.