toss Skrevet 7. mai 2009 Del Skrevet 7. mai 2009 Hei Har laget en subklasse av JTextArea som tegner linjetall på venstre side av området. I en klientklasse legger jeg til denne i en JTabbedPane, men scrollingen fungerer ikke da.. En tidligere versjon brukte JPanel som superklasse, og innholdt bare et JTextArea, men da måtte jeg skrive alle metodene for JTextArea og JTextComponent, så fant ut at jeg heller ville prøve å bruke JTextArea som superklasse. Men nå fungerer altså ikke scrollingen lenger.. Klassen er her: http://pastebin.com/m4a4fac45 evt: import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import javax.accessibility.AccessibleContext; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.text.Document; import javax.swing.text.BadLocationException; /** * * @author Torstein * @author Daniel Sjöblom */ public class JNumberedTextArea2 extends JTextArea { private final static String uiClassID = "NumberedTextArea2UI"; JScrollPane scrollPane; public JNumberedTextArea2() { this(null); } /** * Constructs a new <code>JNumberedTextArea</code> with the text in * the JTextArea * * @param text the text is added to the JTextArea */ public JNumberedTextArea2(String text) { super(text); setMinimumSize(new Dimension(30, 30)); setPreferredSize(new Dimension(30, 30)); setMinimumSize(new Dimension(30, 30)); scrollPane = new JScrollPane(this); } @Override public void paint(Graphics g) { super.paint(g); int charWidth = g.getFontMetrics(this.getFont()).charWidth('0'); int antDigits = (int) Math.log10(this.getLineCount()) + 1; Insets margin = this.getMargin(); margin.left = (charWidth * antDigits + 3); margin.top = 0; this.setMargin(margin); int start = this.viewToModel(scrollPane.getViewport().getViewPosition()); int end = this.viewToModel(new Point( scrollPane.getViewport().getViewPosition().x + this.getWidth(), scrollPane.getViewport().getViewPosition().y + this.getHeight() )); Document doc = this.getDocument(); int startline = doc.getDefaultRootElement().getElementIndex(start) + 1; int endline = doc.getDefaultRootElement().getElementIndex(end) + 1; int fontheight = g.getFontMetrics(this.getFont()).getHeight(); int fontdesc = g.getFontMetrics(this.getFont()).getDescent(); int starting_y = -1; try { starting_y = this.modelToView(start).y - scrollPane.getViewport().getViewPosition().y + fontheight - fontdesc; } catch(BadLocationException e1) { e1.printStackTrace(); } for(int line = startline, y = starting_y; line <= endline; y += fontheight, line++) { g.drawString(Integer.toString(line) + ":", 0, y); } this.repaint(); } } og klienten er her: http://pastebin.com/m2bc38e07 evt: import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.ScrollPaneConstants; class JNumberedTextArea22Client { JNumberedTextArea2 textArea; JFrame frame; public static void main(String[] args) { JNumberedTextArea2 textArea; JFrame frame; JTabbedPane tabbedPane; String content = "Dette er en streng\nDen har flere linjer\nJada.. det har den.."; textArea = new JNumberedTextArea2(content); JNumberedTextArea2 textArea2 = new JNumberedTextArea2(content + content); tabbedPane = new JTabbedPane(); frame = new JFrame("JNumberedTextArea2Client") {}; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container innholdsrute = frame.getContentPane(); tabbedPane.addTab("textArea", textArea); tabbedPane.setMnemonicAt(0, KeyEvent.VK_1); tabbedPane.addTab("textArea2", textArea2); tabbedPane.setMnemonicAt(1, KeyEvent.VK_2); JNumberedTextArea2 comp = new JNumberedTextArea2(content + "\njadda\ntextArea3"); tabbedPane.addTab("textArea3", comp.scrollPane); innholdsrute.setLayout(new BorderLayout()); innholdsrute.add(tabbedPane, BorderLayout.CENTER); frame.pack(); frame.setSize(new Dimension(400, 400)); frame.setVisible(true); } } Takker for all hjelp! Lenke til kommentar
pgdx Skrevet 7. mai 2009 Del Skrevet 7. mai 2009 JScrollPane markise = new JScrollPane(); scrollskit.setViewportView(teksttområde); flate.add(markise); Lenke til kommentar
toss Skrevet 7. mai 2009 Forfatter Del Skrevet 7. mai 2009 (endret) Med mindre jeg missforstår hva du mener med scrollskit er jo dette mer eller mindre den vanlige måten å gjøre dette på.. Det har jeg allerede prøvd. For du mente at koden over skal legges til i klient-klassen? Problemet er at JSsrollPane'et ikke merker at texten er så stor at den må aktiveres. Og jeg må ha et scrollpane i klassen for tekstområdet for at denne måten å gjøre det på skal virke.. EDIT: Er det mulig at en av metodene som er gitt av Scrollable lager rot når den blir arvet? Endret 7. mai 2009 av toss Lenke til kommentar
pgdx Skrevet 8. mai 2009 Del Skrevet 8. mai 2009 Jeg vet ikke om jeg vil lese hele kildekoden din akkurat nå, men her er noe proof of concept (pluss at jeg kjedet meg): http://pastebin.com/m7dba1332 Lenke til kommentar
toss Skrevet 8. mai 2009 Forfatter Del Skrevet 8. mai 2009 Har du i det hele tatt lest innlegget mitt? Jeg vil ha en subklasse av JTextArea som håndterer linjetall på siden.. Klassen du har skrevet her gjør ingen av delene.. Scrolling fungerer, ja, men det i seg selv er ikke problemet.. Men har funnet en annen løsning nå.. Bruker rowHeader for å legge til linjeskift.. Da blir alt nesten slik jeg ønsker det.. Lenke til kommentar
pgdx Skrevet 8. mai 2009 Del Skrevet 8. mai 2009 (endret) Har du i det hele tatt lest innlegget mitt?Nei, er stort sett vant til at folk ikke har peiling og svarer det første jeg antar de lurer på. Beklager det. Du har sikkert allerede sett denne: http://www.velocityreviews.com/forums/t131...-jtextpane.html Hva er det med den som ikke fungerer? Endret 8. mai 2009 av pgdx Lenke til kommentar
toss Skrevet 8. mai 2009 Forfatter Del Skrevet 8. mai 2009 Har sett den, ja.. Problemet er at JTextArea, eller JTextPane som den bruker, ikke er superklassen, og jeg må derfor skrive over alle metodene som setText(), append() osv.. Det er jo for så vidt ikke noe stort problem, og kan også løses ved å ha tekstkomponenten deklarert public. Men jeg ville likevel prøve å se om jeg kunne løse dette på en litt mer elegant måte.. Det nærmeste jeg kommer er dette: import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import javax.accessibility.AccessibleContext; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.text.Document; import javax.swing.text.BadLocationException; /** * * @author Torstein * @author Daniel Sjöblom */ public class JNumberedTextArea2 extends JTextArea { private final static String uiClassID = "NumberedTextArea2UI"; JScrollPane scrollPane; public JNumberedTextArea2() { this(null, null); } /** * Constructs a new <code>JNumberedTextArea</code> with the text in * the JTextArea * * @param text the text is added to the JTextArea */ public JNumberedTextArea2(String text, JScrollPane scrollPane) { super(text); this.scrollPane = scrollPane; } @Override public void paint(Graphics g) { super.paint(g); int charWidth = g.getFontMetrics(this.getFont()).charWidth('0'); int antDigits = (int) Math.log10(this.getLineCount()) + 1; Insets margin = this.getMargin(); margin.left = (charWidth * antDigits + 3); margin.top = 0; this.setMargin(margin); int start = this.viewToModel(scrollPane.getViewport().getViewPosition()); int end = this.viewToModel(new Point( scrollPane.getViewport().getViewPosition().x + this.getWidth(), scrollPane.getViewport().getViewPosition().y + this.getHeight() )); Document doc = this.getDocument(); int startline = doc.getDefaultRootElement().getElementIndex(start) + 1; int endline = doc.getDefaultRootElement().getElementIndex(end) + 1; int fontheight = g.getFontMetrics(this.getFont()).getHeight(); int fontdesc = g.getFontMetrics(this.getFont()).getDescent(); int starting_y = -1; try { starting_y = this.modelToView(start).y - scrollPane.getViewport().getViewPosition().y + fontheight - fontdesc; } catch(BadLocationException e1) { e1.printStackTrace(); } for(int line = startline, y = starting_y; line <= endline; y += fontheight, line++) { g.drawString(Integer.toString(line) + ":", 0, y); } this.repaint(); } public static void main(String[] args) { JFrame frame = new JFrame("JNumberedTextArea2"); Container contPane = frame.getContentPane(); JTabbedPane tabbedPane = new JTabbedPane(); JScrollPane scrollPane = new JScrollPane(); JNumberedTextArea2 textArea = new JNumberedTextArea2("This is a string\nit contains several lines\nindeed", scrollPane); scrollPane.setViewportView(textArea); tabbedPane.addTab("textArea", scrollPane); contPane.add(tabbedPane); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setSize(new Dimension(400, 400)); frame.setVisible(true); } } Problemet her blir at det kjører en evig loop, siden paint-metoden kaller repaint(), og likevel klarer den ikke å få med linjenummer når teksten blir lang nok.. Så nå har jeg egentlig gitt opp å få det til slik jeg tenkte, og baserer meg på å bruke rowHeader i JScrollPane.. Tror jeg lander på noe lignende dette: http://forums.sun.com/thread.jspa?forumID=...974&start=2 Det fungerer egentlig akkurat slik jeg ønsker det, med bare litt ekstra skriving.. Lenke til kommentar
pgdx Skrevet 10. mai 2009 Del Skrevet 10. mai 2009 Har sett den, ja.. Problemet er at JTextArea, eller JTextPane som den bruker, ikke er superklassen, og jeg må derfor skrive over alle metodene som setText(), append() osv..Det sees sjeldent på som et problem (se composition).Det er jo for så vidt ikke noe stort problem, og kan også løses ved å ha tekstkomponenten deklarert public.Nei, det er ikke en god løsning og du bør ikke gjøre det. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå