Portál AbcLinuxu, 10. května 2025 01:53

Dotaz: Java: JTable cell renderer

Jardík avatar 12.8.2010 16:19 Jardík | skóre: 40 | blog: jarda_bloguje
Java: JTable cell renderer
Přečteno: 834×
Odpovědět | Admin
Příloha:
Potřebuji napsat vlastní cell renderer pro JTable (potřebuju renderovat datum ve vlastním formátu). Momentálně mám něco takového:
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".
Věřím v jednoho Boha.

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

12.8.2010 17:06 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Odpovědět | | Sbalit | Link | Blokovat | Admin
Nebylo by lepší v tomhle případě upravit model? Uživatelský renderer s přepsanou metodou 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().
Jardík avatar 12.8.2010 17:46 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Ten kód jsem našel v tutoriálu na stránkách Oraclu. Jinak model vlastní mám, ale ten přece nekreslí. Na nastevení rendereru používám JTable.setDefaultRenderer(Date.class, new DateTableRenderer());. Můj model pro ten column vrací právě Date.class (metoda getColumnClass(int)).
Věřím v jednoho Boha.
Jardík avatar 12.8.2010 17:50 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Jinak DefaultTableCellRenderer.setValue stejně volá setText((value == null) ? "" : value.toString());
Věřím v jednoho Boha.
12.8.2010 17:57 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Mohl byste v module místo data mít rovnou jeho textovou formu. Prve jsem si nevšiml toho pruhování tabulky – to určitě není standardní DefaultTableCellRenderer, ale nějaký uživatelský, takže ten váš budete muset oddědit od toho, který se používá ve zbytku tabulky (a nebo v tom vašem implementovat stejné vykreslování).
Jardík avatar 12.8.2010 19:00 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Tak jsem zjistil, že pokud nenastavím ten renderer, tak se použije vždy renderer z nastavené Look&Feel (pomocí UIManager), v mém případě 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 :-(
Věřím v jednoho Boha.
Jardík avatar 12.8.2010 19:18 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
A teď teda problém kvůli tomu řazení. Když to vrací String, tak můj komparátor pro daný sloupec (nastavený v TableRowSorter.setComparator) dostane k porovnání už ty Stringy.
Věřím v jednoho Boha.
12.8.2010 19:59 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Tak si vytvořte wrapper kolem rendereru. Z tabulky si vytáhnete aktuální renderer, ten vložíte jako implementaci do vašeho wrapperu a tabulce nastavíte jako renderer váš wrapper. A ten wrapper nebude dělat nic jiného, než měnit hodnotu, všechno ostatní deleguje na interní implementaci.
Jardík avatar 12.8.2010 20:25 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Příloha:
Udělal jsem to takto:
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 ...
Věřím v jednoho Boha.
12.8.2010 20:36 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Vrací to 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.
12.8.2010 20:40 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Ještě doporučuju podívat se na Substance look and feel - FAQ dotaz č. 14 a zmíněný odkaz, jestli z toho něco nevyčtete.
Jardík avatar 12.8.2010 21:16 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Java: JTable cell renderer
Moc jste mě nepotěšil :-(
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.
Věřím v jednoho Boha.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.