Rita inmatad text på panel Java, hur?

Permalänk
Medlem

Rita inmatad text på panel Java, hur?

Jag vill i paintComponent metoden rita en sträng, strängen som ska ritas ska vara användarens input, någon som kan ge mig tips på hur jag gör detta? Jag får helt enkelt inte ihop koden.

Jag har skapat en klass Panel extends JPanel och en klass PanelTest extends JFrame. I PanelTest klassen vill jag alltså ta emot användarens input och sedan "rita" denna inputstärng i klassen Panel i paintComponent metoden.

Förmodligen är jag helt ute och cyklar, vet inte ens om jag kan använda mig av Scanner för att ta input i detta fall...

PanelTest klassen:

import java.util.Scanner; import javax.swing.JFrame; /** * * @author */ public class PanelTest extends JFrame { public static void main (String [] args){ Scanner inmatning = new Scanner(System.in); Panel nyPanel = new Panel(); JFrame application = new JFrame(); String namn; String telefon; String epost; System.out.println("Skriv in ditt namn:");//Prompt. namn = inmatning.nextLine(); System.out.println("Skriv in ditt telefonnummer:");//Prompt. telefon = inmatning.nextLine(); System.out.println("Skriv in din e-post adress:");//Prompt. epost = inmatning.nextLine(); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); application.add(nyPanel); application.setSize(250,250); application.setVisible(true); } }

Panel klassen:

import java.awt.Graphics; import javax.swing.JPanel; /** * * @author */ public class Panel extends JPanel { public void paintComponent(Graphics g){ super.paintComponent(g); }//Slut paintComponenet. }

Permalänk
Medlem

Då du inte lägger till någon funktionalitet i PanelTest så behöver du inte extenda JFrame, en vanlig JFrame duger gott. När det kommer till din JPanel är läget ungefär det samma; du kan skriva ut en text genom att lägga till en JLabel.

Du bör döpa om Panel till något mer talande. Vad är det din klass ska göra? Visa en text. Då kanske den ska heta något i stil med TextDisplay. Om du vill att din klass enbart ska visa denna text genom paintComponent() är det troligtvis bättre att ärva direkt från JComponent snarare än JPanel.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Då du inte lägger till någon funktionalitet i PanelTest så behöver du inte extenda JFrame, en vanlig JFrame duger gott. När det kommer till din JPanel är läget ungefär det samma; du kan skriva ut en text genom att lägga till en JLabel.

Du bör döpa om Panel till något mer talande. Vad är det din klass ska göra? Visa en text. Då kanske den ska heta något i stil med TextDisplay. Om du vill att din klass enbart ska visa denna text genom paintComponent() är det troligtvis bättre att ärva direkt från JComponent snarare än JPanel.

Jag ska rita lite rektanglar osv i Panel klassen. Jag vill alltså "rita" texten som är input från användaren på panelen. Gör jag detta med hjälp av en JLabel? Hur använder jag detta? Om jag förstår det hela rätt så vill jag att inputen i klass PanelTest ska visas i klass Panel i en JLabel?

Finns det några bra guider för hur jag gör detta?

Permalänk
Medlem
Skrivet av radera:

Jag ska rita lite rektanglar osv i Panel klassen. Jag vill alltså "rita" texten som är input från användaren på panelen. Gör jag detta med hjälp av en JLabel? Hur använder jag detta? Om jag förstår det hela rätt så vill jag att inputen i klass PanelTest ska visas i klass Panel i en JLabel?

Finns det några bra guider för hur jag gör detta?

En JLabel är en JComponent och läggs till precis som vilken komponent som helst..

JLabel myLabel = new JLabel("Goddag goddag"); myPanel.add(myLabel); // ändras beroende på vilken layout manager som används

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

En JLabel är en JComponent och läggs till precis som vilken komponent som helst..

JLabel myLabel = new JLabel("Goddag goddag"); myPanel.add(myLabel); // ändras beroende på vilken layout manager som används

Men hur får man input från användare att visas istället för "Goddag goddag"? Det är det jag inte kan lista ut helt. Måste jag anropa eller skapa någon speciell metod osv?

Permalänk
Medlem

Det beror på hur du löser användarinmatningen, du kan exempelvis använda den till synes magiska JOptionPane.showInputDialog(...)

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Okej, så som jag gjort ovan med inmatningen är alltså inte rätt? Låt oss säga att jag använder JOptionPane.showInputDialog(...) istället, hur "kopplar" jag då inmatningen till en JLabel?

Permalänk
Medlem
Skrivet av radera:

Okej, så som jag gjort ovan med inmatningen är alltså inte rätt? Låt oss säga att jag använder JOptionPane.showInputDialog(...) istället, hur "kopplar" jag då inmatningen till en JLabel?

Det är inget fel på ditt sätt men det känns som om du tror att det är lite krångligare än det egentligen är..

// ... System.out.println("Skriv in ditt namn:"); namn = inmatning.nextLine(); // eller namn = JOptionPane().showInputDialog("Skriv ditt namn"); JLabel namnLabel = new JLabel(namn); // ... panel.add(namnLabel);

Du skapar alltså en JLabel och lägger till den, precis som du gör med din panel. Tycker egentligen fortfarande att du ska skippa att skapa en ny JFrame-klass då det blir enklare att förstå Java om du förstår tänket bakom objektorientering.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Det är inget fel på ditt sätt men det känns som om du tror att det är lite krångligare än det egentligen är..

// ... System.out.println("Skriv in ditt namn:"); namn = inmatning.nextLine(); // eller namn = JOptionPane().showInputDialog("Skriv ditt namn"); JLabel namnLabel = new JLabel(namn); // ... panel.add(namnLabel);

Du skapar alltså en JLabel och lägger till den, precis som du gör med din panel. Tycker egentligen fortfarande att du ska skippa att skapa en ny JFrame-klass då det blir enklare att förstå Java om du förstår tänket bakom objektorientering.

Kan du visa mig med kod? Blev rörigt för nybörjaren här nu..

Permalänk
Medlem
Skrivet av radera:

Kan du visa mig med kod? Blev rörigt för nybörjaren här nu..

Koden du citerade ska fungera.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Koden du citerade ska fungera.

Så, nu har jag fått det att fungera, men hur sätter jag x och y position för varje JLabel? Har nu tre JLabel och vill visa varje två gången men med olika x och y position...

Permalänk
Medlem
Skrivet av radera:

Så, nu har jag fått det att fungera, men hur sätter jag x och y position för varje JLabel? Har nu tre JLabel och vill visa varje två gången men med olika x och y position...

För att positionera Swing-komponenter används olika Layouts. Det finns en mängd olika som arbetar på lite olika sätt (se http://download.oracle.com/javase/tutorial/uiswing/layout/vis...) men man kan även välja att nulla ut layout-managern och använda så kallad absolut positionering (absolute positioning, http://download.oracle.com/javase/tutorial/uiswing/layout/non...).

När man använder abolut positionering av komponenter går man miste om viss trevlig funktionalitet. Exempelvis anpassar sig inte innehållet i ens Container efter dess storlek. Om du exempelvis förstorar en JFrame så kommer komponenterna ligga kvar på samma plats som innan. Det är detta man försöker undvika genom att använda olika Layouts.

Om du ändå vill positionera komponenter själv sätter du layout till null på den container som kommer innehålla dina komponenter. Komponenternas position anges sedan med setBounds(), se senaste länken ovan.

Rent kodmässigt blir det något sånt här:

private void place(JComponent c, int x, int y) { Dimension d = c.getPreferredSize(); c.setBounds(x, y, d.width, d.height); } nyPanel.setLayout(null); JLabel label1 = new JLabel("Hej"); JLabel label2 = new JLabel("på"); JLabel label3 = new JLabel("dig"); place(label1, 10, 15); place(label2, 50, 40); place(label3, 100, 30);

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Jag får ju inputen att visas på panelen men förstår fortfarande inte hur jag ska kunna sätta x och y position. Jag försöker rita upp två enkla visitkort där inputen ska visas på varje visitkort, dvs namn, telefonnummer och e-post. Jag vill visa varje label ex namnLabel två gånger samtidigt men med olika x och y positioner. Så att namnLabel "inputen" visas på varje visitkort...

Förmodligen en massa fel i koden osv. men som sagt, är nybörjare.

public class Panel extends JPanel { public Panel(){ setBackground(Color.LIGHT_GRAY); } public void paintComponent(Graphics g){ super.paintComponent(g); int teckenStorlek = 18; g.setColor(Color.white); g.fillRect(20, 20, 340, 200); g.drawRect(20, 20, 340, 200); g.setColor(Color.red); g.setFont(new Font("Mistral", Font.ITALIC, teckenStorlek)); g.drawString("VISITKORT 1", 180, 50); g.fillRect(40, 190, 300, 10); g.drawRect(40, 190, 300, 10); g.setColor(Color.white); g.fillRect(20, 240, 340, 200); g.drawRect(20, 240, 340, 200); g.setColor(Color.black); g.setFont(new Font("Courier New", Font.BOLD, teckenStorlek)); g.drawString("VISITKORT 2", 50, 430); g.setColor(Color.green); g.fillRect(300, 240, 60, 200); g.drawRect(300, 240, 60, 200); }//Slut paintComponenet. }

public class PanelTest extends JFrame { public static void main (String [] args){ Panel nyPanel = new Panel(); JFrame application = new JFrame(); String namn = JOptionPane.showInputDialog("Skriv in ditt namn:"); String telefon = JOptionPane.showInputDialog("Skriv in ditt telfonnummer:"); String epost = JOptionPane.showInputDialog("Skriv in din epostadress:"); JLabel namnLabel = new JLabel(namn); JLabel telefonLabel = new JLabel(telefon); JLabel epostLabel = new JLabel(epost); nyPanel.add(namnLabel); nyPanel.add(telefonLabel); nyPanel.add(epostLabel); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); application.add(nyPanel); application.setSize(400,500); application.setVisible(true); } }

Permalänk
Medlem
Skrivet av radera:

Jag får ju inputen att visas på panelen men förstår fortfarande inte hur jag ska kunna sätta x och y position.

...

Mitt förra inlägg beskriver hur du kan göra, har du testat det? När du jobbar med Swings standardkomponenter behöver du inte overrida paintComponent.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Mitt förra inlägg beskriver hur du kan göra, har du testat det? När du jobbar med Swings standardkomponenter behöver du inte overrida paintComponent.

Ja, det har jag testat men får det inte att fungera. Overrida?

Permalänk
Medlem
Skrivet av radera:

Ja, det har jag testat men får det inte att fungera. Overrida?

Det fungerar här. Om du visar vad du har testat så kanske vi kan reda ut problemet.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Det fungerar här. Om du visar vad du har testat så kanske vi kan reda ut problemet.

Har inte min kod tillgänglig nu men vart exakt ska jag sätta din kod? Tror bara jag placerar den fel..

Permalänk
Medlem

Lägg den direkt efter att du skapat din panel. Metoden "place" måste naturligtvis ligga i samma klass. Jag rekommenderar att du tar bort paintComponent() helt.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Lägg den direkt efter att du skapat din panel. Metoden "place" måste naturligtvis ligga i samma klass. Jag rekommenderar att du tar bort paintComponent() helt.

Okej, får försöka med detta. Jag ska alltså lägga denna kod i Panel klassen? I paintComponent metoden?

nyPanel.setLayout(null); JLabel label1 = new JLabel("Hej"); JLabel label2 = new JLabel("på"); JLabel label3 = new JLabel("dig"); place(label1, 10, 15); place(label2, 50, 40); place(label3, 100, 30);

Sedan ska jag alltså lägga till denna metod i Panel klassen innan paintComponent metoden?

private void place(JComponent c, int x, int y) { Dimension d = c.getPreferredSize(); c.setBounds(x, y, d.width, d.height); }

Varför ska jag ta bort paintComponent()? Behöver jag inte denna metod för att kunna rita? Vet faktiskt inte vad jag gör för fel. Har testat alla varianter nu.

Permalänk
Medlem
Skrivet av radera:

Okej, får försöka med detta. Jag ska alltså lägga denna kod i Panel klassen? I paintComponent metoden?

Nej, inte i paintComponent-metoden.

Citat:

Sedan ska jag alltså lägga till denna metod i Panel klassen innan paintComponent metoden?

Så länge du lägger metoden i samma klass så spelar det ingen roll om den ligger före eller efter något annat. Deklarationsordning har ingen betydelse.

Citat:

Varför ska jag ta bort paintComponent()? Behöver jag inte denna metod för att kunna rita? Vet faktiskt inte vad jag gör för fel. Har testat alla varianter nu.

Det beror så på vad du menar med rita. Om du menar "behöver jag denna metod för att kunna visa mina JLabels?" så nej, det gör du inte. Eller rättare sagt, du behöver inte skriva över den, vilket du gör nu. Detta är väldigt viktigt så jag skriver det i fetstilt. I och med att du kör extends JPanel så ärver du en hel massa metoder; det är själva grundidén med att förlänga klasser. Alla JComponents (JPanel, liksom JLabel, förlänger (extends) JComponent) har redan en paintComponent. Det är denna du når när du anropar super.paintComponent(g). Om du tar bort detta anrop kommer du märka att dina JLabels inte längre visas.

Jag rekommenderar å det varmaste att du tar ett steg tillbaka och läser på lite om objektorientering och hur Swing fungerar. Här är en komplett version av mitt tidigare exempel, om du ändå vill experimentera lite:

import java.awt.Dimension; import javax.swing.*; public class Test { private static final int HEIGHT = 100; private static final int WIDTH = 200; Test() { JLabel label1 = new JLabel(JOptionPane.showInputDialog("Sträng 1")); JLabel label2 = new JLabel(JOptionPane.showInputDialog("Sträng 2")); JLabel label3 = new JLabel(JOptionPane.showInputDialog("Sträng 3")); place(label1, 10, 15); place(label2, 50, 40); place(label3, 100, 30); JPanel panel = new JPanel(null); // null-layout panel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); panel.add(label1); panel.add(label2); panel.add(label3); JFrame window = new JFrame("Testfönster"); window.setContentPane(panel); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.pack(); window.setVisible(true); } private void place(JComponent c, int x, int y) { Dimension d = c.getPreferredSize(); c.setBounds(x, y, d.width, d.height); } public static void main(String[] args) { new Test(); } }

Visa signatur

Kom-pa-TI-bilitet