Graphics in normaler Klasse

numpad

Mitglied
Hey,
ich bin gerade dabei, ein kleines Spiel zum üben und lernen zu programmieren, stehe jetzt dennoch (wieder) vor einer Hürde, nämlich will ich einen kleinen Nachrichtendialog anzeigen, welchen ich aber selber programmieren will, heißt nicht den standartdialog, sondern einen mit eigenen Graphics usw.

Ich rufe diesen Dialog über meine "Window"-Class auf, welche so ausieht:
Java:
public class Window {
	
	public Window(){
		
	}
	
	public void showMessage(String text){
		
	}
}
Ja, noch ziemlich mickrig.
Mein Problem besteht darin, dass ich über die "showMessage"-Methode ein Rectangle auf dem Bildschirm zeichnen will.
Das klappt aber nicht, da es nicht über meine "paintComponent()"-Methode in der Hauptklasse aufgerufen wird.

Meine Frage:
Wie kann ich ein einfaches Rectangle über die showMessage-Klasse malen?
Eher gesagt, wie definiere ich hier ein Graphics bzw. Graphics2D Objekt, sodass ich gant einfach
Java:
g.fillRect(50,50,200,200);
anwenden kann?
 
Das Graphics-Objekt bekommst du von AWT oder Swing, du musst also eine entsprechende Komponente verwenden (z.B. ein JFrame das angezeigt wird), selbst wird es nicht erstellt.
 
Man KÖNNTE das Graphics VON der paintComponent-Methode deiner "Hauptklasse" an diese Methode weiterreichen
Java:
private MessageWindow currentWindow = ... // (der Name "Window" ist schon belegt...)

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (currentMessageWindow != null)
    { 
        currentMessageWindow.paintSometingInto(g);
    }

}
Kann aber hakelig werden, wenn man das als "Konzept" in größerem Rahmen umsetzen will. Beschreib' vielleicht mal genauer, worum's geht...
 
Andere Methode: Du erstellst dir ein BufferedImage in gewünschter Grösse und rufst darauf "createGraphics()" auf.
Aber warum der ganze Umstand? Wenn du etwas darstellen willst, kommst du an den Swing, AWT oder SWT ohnehin nicht vorbei.
 
Hab zwar schon ne ganze Weile kein Swing mehr angefasst, aber hier wäre mal ein kleines Beispiel mit einem Dialog bei dem du selbst zeichnen kannst und der dir ein Datenmodell manipuliert
(ein Nachteil von der Variante ist meiner Meinung aber, das man ein Objekt manipuliert das als Parameter übergeben wird (MyData), dafür könnte man aber ähnlich wie bei der JOptionPane eine Methode einrichten die ein Antwort-Objekt zurückgibt das die gesetzten Felder enthält und solange den Thread blockiert (denke ich zu kompliziert? Das ist dann wohl eher was für die Leute hier die besser Swing beherrschen als ich :rtfm: )

Hier mal mein kleines Beispiel:

Java:
public class MyData {

	//Main zum ausführen
	public static void main(String[] args) {
		MyData data = new MyData();
		new MyDialog(data);
	}
	
	private String anyString;
	
	private int anyInt;

	public String getAnyString() {
		return anyString;
	}

	public void setAnyString(String anyString) {
		this.anyString = anyString;
	}

	public int getAnyInt() {
		return anyInt;
	}

	public void setAnyInt(int anyInt) {
		this.anyInt = anyInt;
	}
	
	@Override
	public String toString(){
		return anyString+" - "+anyInt;
	}
}

Java:
@SuppressWarnings("serial")
public class MyDialog extends JDialog {

	private JTextField intInput;
	private JTextField stringInput;
	private JButton okButton;
	private JButton cancelButton;

	private MyData data;

	public MyDialog(MyData data) {
		this.data = data;
		Container cp = new MyConentPane();
		cp.setLayout(new GridLayout(3, 2, 5, 5));
		cp.add(new JLabel("int eingeben"));
		cp.add(new JLabel("String eingeben"));
		intInput = new JTextField();
		intInput.setDocument(new IntegerDocument());
		cp.add(intInput);
		stringInput = new JTextField();
		cp.add(stringInput);
		okButton = new JButton("ok");
		okButton.addActionListener(new OkListener());
		cp.add(okButton);
		cancelButton = new JButton("cancel");
		cancelButton.addActionListener(new CancelListener());
		cp.add(cancelButton);
		setContentPane(cp);
		pack();
		setVisible(true);
	}

	private class MyConentPane extends JPanel {
		@Override
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			g.setColor(Color.PINK);
			g.fillRect(0, 0, getWidth(), getHeight());
		}
	}

	private class OkListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			data.setAnyInt(Integer.parseInt(intInput.getText()));
			data.setAnyString(stringInput.getText());
			closeDialogAndPrintData();
		}

	}

	private void closeDialogAndPrintData() {
		setVisible(false);
		dispose();
		System.out.println(data.toString());
	}

	private class CancelListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			closeDialogAndPrintData();
		}

	}

	@SuppressWarnings("serial")
	public class IntegerDocument extends PlainDocument {
		public void insertString(int offset, String s, AttributeSet attributeSet)
				throws BadLocationException {
			if (s.matches("\\d+")) {
				super.insertString(offset, s, attributeSet);
			}
		}
	}
}

Gruß
 
Man KÖNNTE das Graphics VON der paintComponent-Methode deiner "Hauptklasse" an diese Methode weiterreichen
Java:
private MessageWindow currentWindow = ... // (der Name "Window" ist schon belegt...)

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (currentMessageWindow != null)
    { 
        currentMessageWindow.paintSometingInto(g);
    }

}
Kann aber hakelig werden, wenn man das als "Konzept" in größerem Rahmen umsetzen will. Beschreib' vielleicht mal genauer, worum's geht...

Ich möchte es so haben, dass ich einfach "new MessageWindow(text);" aufrufen kann, ohne dass ich irgendwas in der Hauptklasse in der methode "paintComponent" überprüfen muss, sprich eine eigene MessageBox.
 
Darf ich mal fragen, weshalb du das Rad neu erfinden willst?
Was du willst, ist ja quasi komplett neue Klassen erstellen, die die bestehenden Swingklassen ersetzen.
 
Darf ich mal fragen, weshalb du das Rad neu erfinden willst?
Was du willst, ist ja quasi komplett neue Klassen erstellen, die die bestehenden Swingklassen ersetzen.
Na und? Ist das so verwerflich? Warum denkst du gibt es SWT, JavaFX, entsprechendes Zeugs von Android usw.? Das "Rad" Swing war anscheinend nicht rund genug, von AWT ganz zu schweigen.
Das betrifft meiner Meinung nach nicht nur Window-/Widget-Toolkits. Das ist die "Jeder macht's anders"-Norm und jeder macht's dabei auch noch am besten, zumindest aus seiner Sicht.
[OT]Darüber hatte ich schon heftige Diskussion mit SirWayne und er bewies mir, dass Swing durch JavaFX ersetzt werden soll (wird wohl 'ne ähnliche Geschichte, wie zuvor mit AWT und Swing, nur das diesmal Swing abgelöst werden soll). Aber bitte, was soll dass denn? Man soll das Rad nicht neu erfinden? Wie kommen dann X verschiedene Räder zu Stande, die sich auch noch gegenseitig den Rang ablaufen?
So gesehen:
1. AWT war möglicherweise ein "Reinfall", gut.
2. Swing war wohl dann mehr oder minder eine Schlussfolgerung aus obigem Reinfall? Warum gibt's dann SWT?
3. Erzählt mir blos nicht, JavaFX würde SWT und Swing miteinander vereinen. Welche Existenzberechtigung hätte JavaFX sonst, wenn es sich anmaßt, Swing ersetzen zu können?
4. Alle anderen Window-/Widget-Toolkits sollte man besser meiden.
5. Ein Rad wurde zumindest noch nicht erfunden; Jenes, welches standardmässig auf jeder Plattform verfügbar ist. Evtl. sollte man mal daran arbeiten.[/OT]
 
Na und? Ist das so verwerflich? Warum denkst du gibt es SWT, JavaFX, entsprechendes Zeugs von Android usw.? Das "Rad" Swing war anscheinend nicht rund genug, von AWT ganz zu schweigen.
Das betrifft meiner Meinung nach nicht nur Window-/Widget-Toolkits. Das ist die "Jeder macht's anders"-Norm und jeder macht's dabei auch noch am besten, zumindest aus seiner Sicht.

Vielleicht war meine Frage etwas missverständlich ausgedrückt. Ich frage einfach nur nach den Beweggründen, um zu erfahren, ob er es a) aus dem Grund macht, dass er es besser / selber machen möchte, als es im Original ist oder ob er b) es machen möchte, weil er ein Problem mit den bestehenden Klassen hat, das sich vielleicht auch einfacher lösen lässt.
 
Also dass das einfacher geht, weiss man doch:
Java:
public class SimpleMessage extends JDialog {
  private final JTextArea message = new JTextArea();

  public SimpleMessage(String message) {
    this(message, false);
  }

  public SimpleMessage(String message, boolean modal) {
    super(null, "SimpleMessage", modal);
    add(this.message);
    setMessage(message);
  }

  public void setMessage(String message) {
    if(message == null) {
      throw new NullPointerException();
    }
    this.message.setText(message);
  }

  public void setVisible(boolean flag) {
    if(flag) {
      pack();
    }
    super.setVisible(flag);
  }
}
... und als nächstes macht man sich dann noch Gedanken um Abbruch- und OK-Buttons, denn diese fehlen noch.
 
Oder JOptionPane
Java:
class MyPanel extends JPanel
{
@Override
public void paintComponent(){...}
}
JOptionPane.showMessageDialog(parent,new MyPanel());
 
Oder JOptionPane
Java:
class MyPanel extends JPanel
{
@Override
public void paintComponent(){...}
}
JOptionPane.showMessageDialog(parent,new MyPanel());
😱 😳
Okay, evtl. fragt man ja auch, weil man nicht weiss, dass es doch noch viel einfacher geht. Wie war das mit dem Wald und den Bäumen?
Mich beschleicht aber das Gefühl, dass wir vom Thema abschweifen. Der TO wollte ja ein Graphics-Kontext in einer eigenen Klasse, was aber eigentlich nur Sinn macht, wenn man nicht mit Swing oder AWT hantiert (ob es bei SWT auch mit Graphics geht, enzieht sich meiner Kenntnis). In diesem Fall bliebe einem nur das BufferedImage oder in OpenGL eines der vielen Direct-Versionen, welche man in diesem Forum ebenfalls zu Häuf findet.
 
Zuletzt bearbeitet von einem Moderator:

Neue Themen


Zurück
Oben