abcd423417984 Skrevet 2. juli 2006 Del Skrevet 2. juli 2006 Hei Jeg ønsker å lage et eget swingkomponent (hvis noen vet om gode tutorials om dette så si gjerne i fra) og jeg lurer på en ting; hvordan kan jeg legge til et eller to ANDRE komponenter PÅ komponentet mitt? Altså jeg trenger en måte å tegne opp et eller to andre komponenter (f.eks. JButton eller JList) på et gitt sted og med en gitt størrelse på tegneflaten til JComponent. Noen tanker om hvordan jeg mest mulig korrekt kan oppnå dette? Jeg tenker da på hvordan f.eks. JScrollPane, JSplitPane og JTabbedPane kan ta et hvilket som helst komponent og tegne opp på majoriteten av tegneflaten sin, men frata deler av plassen hvis nødvendig. Takker for eventuelle svar. Lenke til kommentar
HV Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 (endret) Jeg tenker da på hvordan f.eks. JScrollPane, JSplitPane og JTabbedPane kan ta et hvilket som helst komponent og tegne opp på majoriteten av tegneflaten sin, men frata deler av plassen hvis nødvendig. 6423367[/snapback] Jeg skjønner ikke helt hva du egentlig spør om, men det er ikke umulig å lage verken egene komponenter eller egne layouter. Hvis det er en egen layout du er ute etter så er det bare feks å studere hvordan BorderLayout er bygd opp http://java.sun.com/j2se/1.4.2/docs/api/index.html elller kanskje http://java.sun.com/j2se/1.4.2/docs/api/index.html Endret 3. juli 2006 av HV Lenke til kommentar
abcd423417984 Skrevet 3. juli 2006 Forfatter Del Skrevet 3. juli 2006 (endret) Tror du misforstår meg ja. Er nødt til å lage et eget swing-komponent i en sammenheng og dette komponentet må ha et under-komponent slik som JTabbedpane kan ha et hvilket som helst Component inni seg eller som SplitPane som har 2 under-komponenter og tegner opp en border mellom disse. Jeg vet det grunnleggende om hvordan man lager egne komponenter, men sliter litt med å finne ut hvordan man best mulig tegner opp et annet komponent på et gitt område og med en gitt størrelse på det egenlagde komponentets tegneflate. Mao så skal jeg på et eller annet tidspunkt gi MITT egendefinerte komponent beskjed om at "du skal tegne opp dette komponentet også" gjennom en metode ala setUnderKomponent(Componet c) og hver gang paintComponent() eksekveres må da dette underkomponentet tegnes opp riktig. Noen forslag? Det jeg egentlig spør om har ingenting med eksisterende layout-managere å gjøre, men hvordan lage egne swing-komponenter og spesielt dette med samarbeid med andre komponenter. Endret 3. juli 2006 av invictus Lenke til kommentar
HV Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 Tror ikke du finner noen tutorial for dette iallefall:). Sier du hva du skal lage eller? er intressert i å hjelpe. Kan alt dette kortes ned til at du skal male et stort objekt og på den store tingen skal du male en nytt object? For jeg har jo lagd et kart engang som hadde flyttbare kart "tegn" oppå? Blir det riktig eller har jeg sport av igjen da? Trenger ikke flyttes på da. Lenke til kommentar
abcd423417984 Skrevet 3. juli 2006 Forfatter Del Skrevet 3. juli 2006 (endret) Er litt vanskelig å si hva jeg skal lage når jeg ikke helt har bestemt meg. Har bare flere ganger opplevd at eksisterende swing-komponenter er mangelfulle og kunne trengt å lage noe custom med nettopp den egenskapen jeg etterspør her. Bør vel ikke være så alt for vanskelig når flere av swing-komponentene gjør det på akkurat denne måten? Det kan kortes ned til at jeg skal male et komponent (JButton, JTextField, JList, JTable, osv...) på et egendefinert JComponent. class MittKomponent extends JComponent { private Component c = null; public void setKomponentSomSkalTegnes(Component c) { this.c = c; //holder dette? vet swing har en hiarkisk struktur med parents og childs som kanskje kan benyttes? } public void paintComponent(Graphics g) { super.paint(g); //kode for å tegne opp MittKomponent her! //kode for å tegne opp under-komponentet "c" her! Må kunne tegnes opp på et bestemt sted på tegneflaten Graphics g og med en bestemt størrelse. } ... } La oss ta JTabbedPane som en skisse på konseptet: Her ser du hvordan jtabbedpane eksisterer i programmet som et vanlig komponent. Det tabbedpane gjør er å tegne opp noen tabs som den selv kontrollerer, OG et valgfritt Component som man selv kan angi. I dette tilfellet har man sagt at JTabbedPane skal bruke JTextArea og da tegner den opp seg selv OG dette JTextArea komponentet. Se for deg at mitt komponent skal erstatte JTabbedpane i denne applikasjonen. Eneste forskjell er at den istedenfor tabs skal tegne noe annet _rundt_ komponentet. Hvordan sier MITT JComponent at den skal tegne opp et annet komponent på sitt tegnefelt? Endret 3. juli 2006 av invictus Lenke til kommentar
HV Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 ahh klarer ikke konsentrere meg lol alt for varmt. "MittKomponent" er vell det samme som feks en JButton? Du vil egentlig lage din egen CustomPane? eller Vil du lage en feks en CustomButton som feks skal ha en JButton feks nede til venstre? eller Du vil feks lage en ny JButton som inneholder noen extra metoder? Lenke til kommentar
abcd423417984 Skrevet 3. juli 2006 Forfatter Del Skrevet 3. juli 2006 ahh klarer ikke konsentrere meg lol alt for varmt. "MittKomponent" er vell det samme som feks en JButton? Du vil egentlig lage din egen CustomPane? Nei ikke custompane. Et fullverdig komponent som tilfeldigvis holder et annet komponent. Vil du lage en feks en CustomButton som feks skal ha en JButton feks nede til venstre? Tror dette er det nærmeste ja. Skal lage et eget komponent fra scratch, dvs arve fra JComponent, og ta for meg all tegningen selv. Det eneste jeg ikke helt får til er i de tilfeller hvor mitt JComponent inneholder andre komponenter. Derav kodesnutten i forrige innlegget mitt. Først skal mitt JComponent tegne opp alt den skal tegne opp og så skal den tegne opp det komponentet den inneholder. Du vil feks lage en ny JButton som inneholder noen extra metoder? 6427792[/snapback] Nei. Lenke til kommentar
HV Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 (endret) Hvilke egenskaper vil du at din komponent skal ha? Da tenker jeg på flaten som feks skal inneholde en JButton? Endret 3. juli 2006 av HV Lenke til kommentar
abcd423417984 Skrevet 3. juli 2006 Forfatter Del Skrevet 3. juli 2006 Hvilke egenskaper vil du at din komponent skal ha? Da tenker jeg på flaten som feks skal inneholde en JButton? 6427925[/snapback] Det er ikke relevant. Det skal ganske enkelt være et _eget_ component som arver fra JComponent og inneholder et annet komponent. Andre egenskaper er irrelevant ettersom dette faktisk bare er utprøving av et konsept. Tror jeg gir opp hele dette prosjektet fordi det bør ikke være nødvendig å bruke 4 lange innlegg på å beskrive en såpass grunnleggende problemstilling Det er nesten så jeg tror du håner meg her...Hvis ikke takker jeg for forsøket på å hjelpe meg. Har prøvd å finne svar på dette på internett en god stund nå uten resultat dessverre. Det er mye lettere å finne svar på det nøyaktig samme i .NET. Lenke til kommentar
HV Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 Ingenting er håning, prøver å lage en slik komponent, men hva skal man lage hvis man skal lage noe som ikke har noen funksjonalitet? Men siden du sier at egenskapene er irelevant, mener jeg at du kanskje bare prøver å finne opp hjulet på nytt. Java er jo veldig utviklet etter min mening, så jeg ser kanskje ikke behovet for å finne opp en ny komponent uten noen spesielle egenskaper. Kanskje du må tenke igjennom formålet med den nye komponenten? Hvis du sier at du trenger en komponent som inneholder en annen komponent men den komponenten trenger nødvendgvis ikke ha noen egenskaper, så blir det jo som å male et hus i grønt for så å male det rødt. Du kan legge en Jbutton rett i en container, men det går jo også ann å legge den samme knappen i et Jpanel og så legge jpanelet inn i containerer og du får jo samme resultatet. Men med mindre du ikke tenger funksjonlitaten til JPanel er det jo ikke vits. Hvis du heller ikke trenger noen annen funksjonalitet så er det jo ikke noen vits i å legge inn et extra lag. Man extender jo heller ikke hvilken som helst klasse bare for å gjøre det, det koster jo litt. Vennlig hilsen HV Lenke til kommentar
abcd423417984 Skrevet 3. juli 2006 Forfatter Del Skrevet 3. juli 2006 (endret) Ja jeg forstår poenget ditt, men dette er et ganske generic prosjekt. For et halvt år siden trengte jeg et custom-komponent med akkurat denne muligheten, men måtte legge hele greia på hylla ettersom jeg ikke fant ut hvordan man kunne gjøre det (var ikke langt unna å gå for .NET istedenfor ettersom det der var godt dokumentert). Det er utrolig surt å ha halve prosjektet ferdig for så å finne ut at det ikke er mulig å finne informasjon om hvordan man fikser den siste biten. Jeg skal lage egne komponenter ved behov, men først må jeg vite hvordan jeg gjør det. Derav tester jeg konseptet slik det er gjort i mange swing-komponenter. Jeg trenger funksjonalitet, men akkurat nå tenker jeg ikke i de baner da det er viktigst for meg å vite _hvordan_ jeg gjør noe før jeg faktisk gjør det. Swing er dessverre et bibliotek med mangler, og derfor er det for mine prosjekter essensielt å kunne utvide det ved behov...Dog vet jeg ingenting om mine fremtidige prosjekter på dette tidspunkt og det er derfor svært vanskelig å komme med en konkret eksempel på hva jeg skal lage. Vil bare lære meg teknikken så jeg kan den til da jeg faktisk trenger det. Takker alikevel så mye for hjelpen. Endret 3. juli 2006 av invictus Lenke til kommentar
HV Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 Lykke til, kan hende komponenten ser dagens lys av seg selv hvis den får en grunn til å eksistere. Personlig har ikke jeg funnet noen esensielle mangler. Lenke til kommentar
blackbrrd Skrevet 3. juli 2006 Del Skrevet 3. juli 2006 Å si at swing er dårlig dokumentert er egentlig litt merkelig ettersom du har tilgang til hele kildekoden og kan se hvordan f.eks JButton og JPanel er laget. Personlig så ville jeg f.eks gått for å extende en eksisterende komponent, ikke JComponent. Grunnen er ganske enkel den at det er kjappere å bruke byggeklosser enn å lage alt selv. Det er et av grunnprinsippene ved objektorientert programmering. F.eks la oss si at jeg vil ha et tekstfelt som er knyttet til en slider. Dvs at du kan endre data enten ved å skrive inn ett tall, eller ved å dra slideren opp og ned. Her er et eksempel på den koden: package no.deltasoft.harp.gui; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2002</p> * <p>Company: </p> * @author not attributable * @version 1.0 */ import java.awt.*; import javax.swing.*; import javax.swing.event.*; public class SliderAndTextFieldEditor extends JPanel { BorderLayout borderLayout1 = new BorderLayout(); JSlider js = new JSlider(); JTextField jtf = new JTextField(); public SliderAndTextFieldEditor() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } } private void jbInit() throws Exception { this.setLayout(borderLayout1); jtf.setPreferredSize(new Dimension(30, 21)); js.addChangeListener(new SliderAndTextFieldEditor_js_changeAdapter(this)); this.add(js, BorderLayout.CENTER); this.add(jtf, BorderLayout.EAST); } public void setMinimum(int iMin) { js.setMinimum(iMin); } public void setMaximum(int iMax) { js.setMaximum(iMax); } public void setValue(int iValue) { jtf.setText("" + iValue); js.setValue(iValue); } public String getValue() { return jtf.getText(); } void js_stateChanged(ChangeEvent e) { jtf.setText("" + js.getValue()); } class SliderAndTextFieldEditor_js_changeAdapter implements javax.swing.event.ChangeListener { SliderAndTextFieldEditor adaptee; SliderAndTextFieldEditor_js_changeAdapter(SliderAndTextFieldEditor adaptee) { this.adaptee = adaptee; } public void stateChanged(ChangeEvent e) { adaptee.js_stateChanged(e); } } } Kan forresten anbefale Jbuilder for å bli bedre kjent med java api'n ettersom den har en praktisk høyreklikk->view definition sak når du holder musa over en klasse, da går det rimelig kjappt å bla seg igjennom klasser. Her er f.eks koden til JPanel, en generisk container: /* * @(#)JPanel.java 1.44 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.swing; import java.awt.*; import javax.swing.plaf.*; import javax.accessibility.*; import java.io.Serializable; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.IOException; /** * <code>JPanel</code> is a generic lightweight container. * For examples and task-oriented documentation for JPanel, see * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/panel.html">How to Use Panels</a>, * a section in <em>The Java Tutorial</em>. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @beaninfo * description: A generic lightweight container. * * @version 1.44 01/23/03 * @author Arnaud Weber * @author Steve Wilson */ public class JPanel extends JComponent implements Accessible { /** * @see #getUIClassID * @see #readObject */ private static final String uiClassID = "PanelUI"; /** * Creates a new JPanel with the specified layout manager and buffering * strategy. * * @param layout the LayoutManager to use * @param isDoubleBuffered a boolean, true for double-buffering, which * uses additional memory space to achieve fast, flicker-free * updates */ public JPanel(LayoutManager layout, boolean isDoubleBuffered) { setLayout(layout); setDoubleBuffered(isDoubleBuffered); setOpaque(true); updateUI(); } /** * Create a new buffered JPanel with the specified layout manager * * @param layout the LayoutManager to use */ public JPanel(LayoutManager layout) { this(layout, true); } /** * Creates a new <code>JPanel</code> with <code>FlowLayout</code> * and the specified buffering strategy. * If <code>isDoubleBuffered</code> is true, the <code>JPanel</code> * will use a double buffer. * * @param isDoubleBuffered a boolean, true for double-buffering, which * uses additional memory space to achieve fast, flicker-free * updates */ public JPanel(boolean isDoubleBuffered) { this(new FlowLayout(), isDoubleBuffered); } /** * Creates a new <code>JPanel</code> with a double buffer * and a flow layout. */ public JPanel() { this(true); } /** * Resets the UI property with a value from the current look and feel. * * @see JComponent#updateUI */ public void updateUI() { setUI((PanelUI)UIManager.getUI(this)); } /** * Returns the look and feel (L&F) object that renders this component. * * @return the PanelUI object that renders this component * @since 1.4 */ public PanelUI getUI() { return (PanelUI)ui; } /** * Sets the look and feel (L&F) object that renders this component. * * @param ui the PanelUI L&F object * @see UIDefaults#getUI * @since 1.4 * @beaninfo * bound: true * hidden: true * attribute: visualUpdate true * description: The UI object that implements the Component's LookAndFeel. */ public void setUI(PanelUI ui) { super.setUI(ui); } /** * Returns a string that specifies the name of the L&F class * that renders this component. * * @return "PanelUI" * @see JComponent#getUIClassID * @see UIDefaults#getUI * @beaninfo * expert: true * description: A string that specifies the name of the L&F class. */ public String getUIClassID() { return uiClassID; } /** * See readObject() and writeObject() in JComponent for more * information about serialization in Swing. */ private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); if (getUIClassID().equals(uiClassID)) { byte count = JComponent.getWriteObjCounter(this); JComponent.setWriteObjCounter(this, --count); if (count == 0 && ui != null) { ui.installUI(this); } } } /** * Returns a string representation of this JPanel. This method * is intended to be used only for debugging purposes, and the * content and format of the returned string may vary between * implementations. The returned string may be empty but may not * be <code>null</code>. * * @return a string representation of this JPanel. */ protected String paramString() { return super.paramString(); } ///////////////// // Accessibility support //////////////// /** * Gets the AccessibleContext associated with this JPanel. * For JPanels, the AccessibleContext takes the form of an * AccessibleJPanel. * A new AccessibleJPanel instance is created if necessary. * * @return an AccessibleJPanel that serves as the * AccessibleContext of this JPanel */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessibleJPanel(); } return accessibleContext; } /** * This class implements accessibility support for the * <code>JPanel</code> class. It provides an implementation of the * Java Accessibility API appropriate to panel user-interface * elements. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ protected class AccessibleJPanel extends AccessibleJComponent { /** * Get the role of this object. * * @return an instance of AccessibleRole describing the role of the * object */ public AccessibleRole getAccessibleRole() { return AccessibleRole.PANEL; } } } 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å