12. november 2004 - 18:03Der er
13 kommentarer og 1 løsning
Jlist og ListCellRenderer
Jeg har skrevet mig egen ListCellRenderer for at vinde lidt hastighed. Nå jeg kører JRE 1.5 er jeg nød til at kalde setMaximumSize, setMinimumSize, setPreferredSize før at rækkerne bliver synlige (Ellers er de 0 pixels høje). For det første undre jeg mig over hvordan jeg kan kalde disse metoder på Component, som jo ikke er en JComponent. For det andet virker dette ikke i 1.4 og før. Hvordan arver jeg fra Component, og får min rækker til at være synlige i JRE 1.3+
class ListCellRendererNew extends Component implements ListCellRenderer {
public ListCellRendererNew() { setMaximumSize(new Dimension(150,16)); setMinimumSize(new Dimension(150,16)); setPreferredSize(new Dimension(150,16)); }
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Troede du havde løst den - (hvis den hænger sammen med et tidligere spørgsmål)
Prøv den her, fordeler ca. 60/40
import java.awt.*; import javax.swing.*;
public class ListLeaders { static class MyCellRenderer extends JPanel implements ListCellRenderer { JLabel left; JLabel right; MyCellRenderer() { setLayout(new GridBagLayout()); left = new JLabel(); right = new JLabel(); left.setOpaque(true); right.setOpaque(true);
Ja jeg fik det løst. Problemet er bare er når man nu bruger JPanel, JLabels og så videre, så begynder en JList at performe rigtig dårlig. Derfor har jeg lavet min egen som arver fra Component. I paint metoden bruger jeg drawString og må derfor selv regne placerigen ud. Tilgengæld kan jeg få det præcis som jeg vil, og det perfomer meget bedre. Men det giver mig desværre dette problem med højden.
Jeg arbejder på en langsom CPU. Her er det tydligere : 70-80% ved ingen listCellRenderer, men 100% ved bare en simple listCellRenderer med flere JLables. Bruger jeg Component og drawString ryger jeg ned på 60-65%. Dvs. hurtigere end standard listCellRenderer!
Jeg ønsker også at bruge Component fordi det er meget flexibelt. Men jeg har stadigvæk problemer med højden. Har du set linket fra google?
Og det betragter jeg egentlig ikke som noget problem ved 100.000 elementer, men er vi ikke der henne hvor antallet af elementer skal minimeres, en JList med 5000 elementer ville jeg betragte som uoverskuelig for brugeren.
Jeg har kun skimmet linket, men da dine CPU tal viser en mulighed vil jeg kigge på det. Vender tilbage i løbet af weekenden (nok ikke før søndag) håber det går.
Det lyder godt, og jo det begynder at blive uoverskueligt med så mange elementer. Performanve på JListen er ikke afhængig af antal elementer (og dog - sikkert lidt), men hvor stor JListen er på skærmen, og hvor tung ListCellRenderer'n er. Det må være muligt at kunne få det til at virke med Component, så jeg håber du finder tricket!
Fik lige tid til at kigge på det her fra formiddagen af, og jeg må jo pænt give dig ret, man kan godt vinde op til 40% i CPU forbrug, man mister så også lidt af JLabels indbyggede funktionalitet, men har man ikke for den er det jo ligegyldigt.
Et Component object har per definition en størrelse på 0,0 indtil en sådan er defineret, derfor skal du som minimum override getPreferredSize() i klassen og derved give objectet en størrelse.
Du kan sikkert trimme denne cellRenderer en lille smule mere ved at lave en constructor der tager en JList som parameter og definere renderens farver udfra parameteren, i stedet for som jeg gjort at kalde list.getSelectionBackground() etc.
Jeg vil tillade mig at kalde det et svar!
Prøv den: minJList.setCellRenderer( new LayoutColumnRenderer());
class LayoutColumnRenderer extends Component implements ListCellRenderer{ public LayoutColumnRenderer(){ }
public LayoutColumnRenderer(int width, int height){ this.width = width; this.height = height; }
public Dimension getPreferredSize(){ return new Dimension(width, height); }
public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean hasFocus) {
text = value.toString(); this.list = list; this.select = isSelected;
// udkommenter evt. denne linie og erstat fm.getAscent() med 2 eller 3 // måske vinder du en brøkdel i performance ved det. fm = g.getFontMetrics(g.getFont());
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.