Methoden Gedanken Anstöße zur Realisierung zweier Ideen (Grafisch Sekunden zählen und Frameaufteilung)

AndyFFW

Mitglied
Hallo,

ich brauche mal Ideen zur Verwirklichung zweier Aktionen:

1. Schreib ich derzeit ein Programm welches die shutdown.exe ausführt wo man aber Parameter eingeben kann die das Programm dann der exe übergibt (Timeout, shutdown, restart). Nach dem starten kommt ein neues Fenster welches die Zeit anzeigt die man eingegeben hat und ein Abbruch Button. Ich brauch jetz die Lösung wie ich da einen Countdown einfüge (und wo und was für einen) und ob ich da sogar einen neuen Thread für brauche.


2. Hab ich ein Fenster mit derzeit fester größe mit einem Hintergrundbild und ich will alle weiteren Komponenten da drüber legen.

Ich hab das bis jetzt so gelöst:
Das Hintergrundbild hab ich in ein JLabel gepackt und so groß wie das JFrame gemacht. Dadrüber hab ich ein Transparentes JPanel gepackt welches das Main-Panel darstellt und ein BorderLayout hat. Alle weiteren Komponenten hab ich per BorderLayout so in das Main - Panel gelegt als wäre das Panel das eigtl Frame.
Von der Theorie her eigtl ne runde Sache - hab dann erstmal ne Überschrift drüber gelegt und sie dem BorderLayout North übergeben -> hat wunderbar geklappt. Jetz hab ich noch ein weiteres JPanel (welches n JTextField, n JPasswordField und n JButton enthält) in South dazugefügt aber es wurde einfach rechts neben der Überschrift zugefügt. Hab dann noch n bissl rumgefummelt und jetzt ist es zwar am unteren Rand aber 1. zu weit und 2. hat dieses Panel das Bild Quer geteilt.
Also Vermute ich das der Aufbau JFrame -> JLabel mit Bild und da drüber JPanel mit weiteren Komponenten nicht gut gelöst ist...
Daher die Frage: Wie bau ich n GUI mit nem Hintergrundbild worauf weitere Komponenten sind welche aber das Bild (bzw. das JLabel mit dem Bild) nicht verschieben o. ä. ?
 

Marco13

Top Contributor
An sich klingt das schon nicht komplett verkehrt. Ich würde aber überlegen, ein "ImagePanel extends JPanel" zu machen, das das Hintergrundbild zeichnet. Das könnte man ins ContentPane des Frames legen, dann spart man sich den Krampf mit transparenzen und mehreren Schichten, und es könnte das Layout vereinfachen (irgendwo musst du da doch jetzt ein null-Layout haben, oder?).

Zum Layout an sich ... joa, wenn's ohne Hintergrundbild passt, kriegt man's auch MIT Hintergrundbild hin, also im Zweifelsfall erstmal ohne versuchen und dann bescheid sagen.
 

AndyFFW

Mitglied
An sich klingt das schon nicht komplett verkehrt. Ich würde aber überlegen, ein "ImagePanel extends JPanel" zu machen, das das Hintergrundbild zeichnet. Das könnte man ins ContentPane des Frames legen, dann spart man sich den Krampf mit transparenzen und mehreren Schichten, und es könnte das Layout vereinfachen (irgendwo musst du da doch jetzt ein null-Layout haben, oder?).

Zum Layout an sich ... joa, wenn's ohne Hintergrundbild passt, kriegt man's auch MIT Hintergrundbild hin, also im Zweifelsfall erstmal ohne versuchen und dann bescheid sagen.

Also das Frame hat kein Layout da es ja nur n Label mit Bild enthält und dadrüber halt n Panel mit BorderLayout welches ich dann so wie das eigtl Fenster behandle.
ImagePanel extends JPanel -> ne eigene Klasse die von JPanel erbt? Wenn ich die so schreibe das sie mein Hintergrundbild ist erstelle ich ein Objekt von und füge dies dem eigtl GUI zu? Wenn ja wie adde ich es dann? Und ist das die Normale vorgehensweise? Ich schreibt ja öfter Programme die n Hintergrundbild haben und der Rest liegt drauf.

Na ohne Hintergrundbild klar dan geb ich dem ContentPane vom JFrame n BorderLayout und füg das dann rein-aber im Normalfall überschneidet sich da ja nichts da alle Bereiche nebeneinander liegen.

Danke für Antworten
 

Marco13

Top Contributor
Also das Frame hat kein Layout da es ja nur n Label mit Bild enthält und dadrüber halt n Panel mit BorderLayout welches ich dann so wie das eigtl Fenster behandle.
...

Das ContentPane (also "der Frame") hat schon ein Layout, auch wenn man es nicht explizit setzt. Wenn du sagst "dadrüber halt n Panel" klingt das schon, als würde da potentiell das Layout zerhauen. Man sollte nicht schreiben
frame.add(somePanel);
sondern
frame.getContentPane().add(somePanel);
(auch wenn es fast das gleiche ist, zumindest der Deutlichkeit halber).

Ansonsten wären ein paar Zeilen Code nicht schlecht, damit man genauer sieht, was du meinst (und wo es ihn da ggf. raushaut...)
 

AndyFFW

Mitglied
Das ContentPane (also "der Frame") hat schon ein Layout, auch wenn man es nicht explizit setzt. Wenn du sagst "dadrüber halt n Panel" klingt das schon, als würde da potentiell das Layout zerhauen. Man sollte nicht schreiben
frame.add(somePanel);
sondern
frame.getContentPane().add(somePanel);
(auch wenn es fast das gleiche ist, zumindest der Deutlichkeit halber).

Ansonsten wären ein paar Zeilen Code nicht schlecht, damit man genauer sieht, was du meinst (und wo es ihn da ggf. raushaut...)

Also ich hab nach weiterem googlen ne neue scheinbare Möglichkeit gefunden: Die setContentPane() Methode. Da die Methode einen neuen Fensterinhalt setzt und die getContentPane().add... Methode etwas auf den Fensterinhalt draufsetzt habe ich nun mein JLabel (mit dem Bild) mit der setContentPane() Methode dem Fenster zugefügt und danach erstmal ein JPanel mit JFrame.getContentPane().add(JPanel) hinzugefügt - vom logischem her ne topp Lösung, nur klappt dies nicht. Es ist nur das Hintergrundbild zu sehen...

Hier der Code fürs Hintergrundbild und das JPanel.

Java:
JLabel labelBackground = new JLabel(new ImageIcon(getClass().getResource("Background1.jpg")));
frameMain.setContentPane(labelBackground);

headline.setFont(fontHeadline);								// Create Headline
headline.setForeground(Color.RED);
headline.setEditable(false);
headline.setFocusable(false);
headline.setOpaque(true);
headline.setBorder(null);
panelNorth.add(headline);
frameMain.getContentPane().add(BorderLayout.NORTH, panelNorth);		// Add Headline
 

Marco13

Top Contributor
Java:
class ImagePanel extends JPanel
{
    private final Image image;

    public ImagePanel(Image image)
    {
        this.image = image;
        setOpaque(false);
    }

    @Override
    public void paint(Graphics g)
    {
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
        super.paint(g);
    }
}
So eins erstellen, mit setContentPane(imagePanel) setzen, und dann so tun, als wäre das ein ganz normales Panel bzw. ein ganz normales ContentPane
 

AndyFFW

Mitglied
Java:
class ImagePanel extends JPanel
{
    private final Image image;

    public ImagePanel(Image image)
    {
        this.image = image;
        setOpaque(false);
    }

    @Override
    public void paint(Graphics g)
    {
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
        super.paint(g);
    }
}
So eins erstellen, mit setContentPane(imagePanel) setzen, und dann so tun, als wäre das ein ganz normales Panel bzw. ein ganz normales ContentPane

Also soll ich das Bild in den Typ Image dieser Klasse packen? Wie läuft das ab? Ich hab ja das Bild in dem Typ ImageIcon aber das lässt sich nicht konvertieren... Oder kann ich anstatt einem Image ein ImageIcon nehmen und dieses der Methode übergeben?
 

Marco13

Top Contributor
Ja, im Zweifelsfall mit
Java:
Image image = new ImageIcon(getClass().getResource("Background1.jpg")).getImage();
ImagePanel imagePanel = new ImagePanel(image);
setContentPane(imagePanel);
// Jetzt ganz normal weiter...
getContentPane().setLayout(...);
getContentPane().add(...);
 

AndyFFW

Mitglied
Ja, im Zweifelsfall mit
Java:
Image image = new ImageIcon(getClass().getResource("Background1.jpg")).getImage();
ImagePanel imagePanel = new ImagePanel(image);
setContentPane(imagePanel);
// Jetzt ganz normal weiter...
getContentPane().setLayout(...);
getContentPane().add(...);

Ah ok ja das geht bisher, danke!

Und zu meinem anderen Problem? Ich tippe mal darauf das ich nen zweiten Thread brauche oder?
 

Marco13

Top Contributor
Hm. Kommt drauf an, wie der Timer an sich umgesetzt ist. Mit einem SwingTimer könnte das gehen, aber ggf. musst du das nochmal genauer beschreiben.
 

AndyFFW

Mitglied
Hm. Kommt drauf an, wie der Timer an sich umgesetzt ist. Mit einem SwingTimer könnte das gehen, aber ggf. musst du das nochmal genauer beschreiben.

Ich hab noch keinen Timer. Wolls erst mit na Dauerschleife machen aber die legt das Programm lahm - die könnte höchstens in nem zweiten Thread laufen... Was ist denn am besten und einfachsten zu empfehlen? Ich will einfach nur von einer Variablen X, sekündlich runterzählen.
 

AndyFFW

Mitglied

Also ich hab mir das jetz mal reingezogen und n Video zu angeschaut und mit den Infos n Quellcode geschrieben um mit dem Timer n bisschen rum zu experimentieren. Jedoch wurde das Programm nach dem starten sofort beendet. Und danach hab ich 1:1 den Quellcode aus dem Video abgeschrieben in dem eine Sekündliche Stoppuhr in der Konsole läuft aber bei mir läuft nur eine Sekunde ab. Hier der Quellcode

Java:
public class Main extends JFrame {
	
	private Timer timer;
	public int count = 0;
	
	public Main() {
		
		timer = new Timer(1000, new TimerListener());
		timer.start();
		
	}
	
	private class TimerListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			
			count++;
			System.out.println(count);
			
		}	
	}
	
	public static void main(String[] args) {
		
		new Main();
		
	}
	
}
 

AndyFFW

Mitglied
Anhang zum meinem letzten Post:

wenn ich die Zeit auf 500 stelle geht es. Ich kriege alle halbe sekunde eine Ausgabe. Bis 900 msec ca funktioniert es... woran liegt das?
 
M

Marcinek

Gast
Weil das Programm sofort beendet wird und der SwingTimer keinen seperaten Thread öffnet.
 

AndyFFW

Mitglied
Weil das Programm sofort beendet wird und der SwingTimer keinen seperaten Thread öffnet.

Naja das ist keine erklärung - nochmal die genaue Sachlage:

Wenn ich bei diesem Quellcode die Zeit des Timers auf 1000 setze führt der Timer einmal die Methode seines ActionListener's aus und das Programm wird beendet.
Wenn ich die Zeit aber auf z.B. 500 setze wird die Methode im halb sekündlichen Takt dauerhaft ausgeführt bis ich selber das Programm beende.
Warum funktioniert der Timer also nur bei z.B einer halben Sekunde und nicht bei einer ganzen?
(Timer Methoden wie setRepeat und so hab ich schon ausprobiert)
 

AndyFFW

Mitglied
Ok hab das Geheimnis gelüftet. Warum der Timer bei einer halbe Sekunde ging und bei einer ganzen weiß ich nicht aber der Timer ist eigtl nur mit einem funktionierenden GUI zu nutzen.

Danke für die Hilfe!

(Noch ne kleine Frage am Rande: Weiß jmnd wie man einen Minecraft Login schreibt oder kennt jmnd jemanden der das weiß? Nich meckern wegen Off-Topic oder so aber da ich eh hier schreibe wollte ich gleichmal rumfragen)
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben