Auf JPanel malen und davor JComponenten anzeigen

Diskutiere Auf JPanel malen und davor JComponenten anzeigen im AWT, Swing, JavaFX & SWT Bereich.
E

Eichelhäer

Hallo,

ich möchte auf ein JPanel malen und dabei gleichzeitig im Vordergrund JComponenten wie Buttons oder kleinere Labels anzeigen.
Mit einem JLabel, das mit einem ImageIcon versehen ist, zusätzlich auf dem JPanel geht es zwar, nur bietet ImageIcon keine angepasste Größenanpassung des beliebigen Icons (auch gif) bei unterschiedlichen Auflösungen. Aus diesem Grunde möchte ich auf das JPanel malen und zugleich die Componenten darauf legen.
Ist das überhaupt möglich?
 
E

Eichelhäer

Ok, ich habs grade mit repaint jeder einzelnen Componente probiert. Geht zwar, aber flackert trotz set DoubleBuffered true. Wie stellt man das ab?
 
MoxxiManagarm

MoxxiManagarm

Ohne Code kann man schlecht was dazu sagen. Aber repaint in jeder einzelnen Methode klingt schon mal nicht so prall.
 
mihe7

mihe7

Ich hatte für jemanden hier mal was zusammengeschustert,
Java:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class ImagePanel extends JPanel {
    private BufferedImage image;
    private Image scaled;

    public ImagePanel(BufferedImage image) {
        this.image = image;
    }

    @Override
    public Dimension getPreferredSize() {
        Insets insets = getInsets();
        int width = insets.left + insets.right + image.getWidth();
        int height = insets.top + insets.bottom + image.getHeight();
        return new Dimension(width, height);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Insets insets = getInsets();
        g.drawImage(getScaled(), insets.left, insets.top, null);
    }

    private Image getScaled() {
        Insets insets = getInsets();
        int w = getWidth() - insets.left - insets.right;
        int h = getHeight() - insets.top - insets.bottom;

        if (scaled == null || scaled.getWidth(null) != w || scaled.getHeight(null) != h) {
            scaled = image.getScaledInstance(w, h, Image.SCALE_SMOOTH);
        }
    }
}
Und was zum Spielen:

Java:
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Test {
    public static void main(String[] args) throws Exception {
        BufferedImage img = ImageIO.read(new URL("https://upload.wikimedia.org/" +
                "wikipedia/commons/thumb/7/77/Wikipedia_svg_logo.svg/" +
                "768px-Wikipedia_svg_logo.svg.png"));

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JPanel panel = new ImagePanel(img);
                panel.add(new JButton("Test"));
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.add(panel);
                frame.pack();
                frame.setVisible(true);
            }

        });
    }
}
 
E

Eichelhäer

hh ja stimmt wohl^^.

naja ich habe ne classe Screen die von nem JPanel erbt. Dann hab ich ne Klasse die meine buttons labels und comboxes etc. verwalten und dem screen objekt, das der zweiten klasse über den Konstruktor übergeben wird, hinzufügt. In dieser Klasse hole ich mir mit getGraphics() die Grafik aus der screen klasse und male dann in der zweiten klasse. Diese zweite klasse läuft ihrerseits wieder in nem eigenem Thread also mit run- Methode. Das funzt alles schon recht gut. Insgesamt hat mein Programm 3 Threads aber das mit dem malen klappt eben nicht.

Hier mal bisl pseudo Code:

Code:
public class GameThread extends Thread {

    public GameThread() {
        screen = new Screen();
        mainmenu = new MainMenu(screen);
        game = new Game(screen);
    }

    @Override
    public void run() {
    
    //Thread behandlung eher umfangreich
    
    }
    
}

public class MainMenu extends Thread {

    private Screen screen = null;

    public MainMenu(Screen screen) {
        this.screen = screen;
        
        mainMenuButtons = new ArrayList<JButton>();
        singlePlayerMenuButtons = new ArrayList<JButton>();
        singlePlayerMenuLabels = new ArrayList<JLabel>();
        multiPlayerMenuButtons = new ArrayList<JButton>();
        multiPlayerMenuLabels = new ArrayList<JLabel>();
        optionMenuButtons = new ArrayList<JButton>();
        optionMenuLabels = new ArrayList<JLabel>();
        humanCampaignButtons = new ArrayList<JButton>();
        
        backgroundLabel = new JLabel();
        backgroundLabel.setLayout(null);
        backgroundLabel.setIcon(new ImageIcon("res/menu/backgrounds/mainmenuBackground1280.png"));
        
        initComponents(backgroundLabel);
        
        initMainMenuButtonsActions();
        initSinglePlayerButtonsActions();
        initMultiPlayerButtonsActions();
        initOptionMenuActions();
        initSinglePlayerActions();
        
        screen.add(backgroundLabel);
        screen.changeFullscreenMode();
    }

    public void render() {
        Graphics g = screen.getGraphics();
        
        backgroundLabel.repaint();
        timeLabel.repaint();
        
        // und der rest der componenten
        
    }
}
 
E

Eichelhäer

Prinzipiell hab ichs verstanden und muss es halt nur noch für meine Zwecke anpassen.

ABER ich habe noch ne Frage:

Im AWT package gibt es die Klassen GraphicsEnvironment, GraphicsDevice und DisplayMode. Mithilfe dieser Klassen erzeuge ich meinen Screen sowohl im Fullscreen als auch im Fenstermodus. Hier nun meine Frage: Inwieweit ist Java mitzuhilfenahme dieser Klassen fähig auf die eingebaute(n) grafikkarten zuzugreifen also bei nur einem Screen? Und wie bekommt man den Namen der Grafikkarte angezeigt als String?

Ich habe nämlich vor in meinem Programm dem Benutzer die Wahl seiner eingebauten Grafikkarte(n) zu überlassen.
Dasgleiche gilt auch für den Sound also ob eingebautes Micro(Laptop) oder beispielsweise Headset, oder externe oder interne Lautsprecher.

Ich möchte mir in einer Combobox die namen der Geräte anzeigen lassen und den Benutzer auswählen lassen.
 
mihe7

mihe7

Den Namen der GraKa: keine Ahnung, ob das in Java möglich ist. Die ID des GraphicsDevice lässt sich anzeigen. Unter X gibt es dann das Display ":0.0".
 
E

Eichelhäer

Was meinst du mit X ? Also ich habe mit GraphicsConfiguration[] Zugriff auf die Id des displays.Da ich nur einen Screen habe ist das 0.
Mit System.getProperties() bekommt man auch einige infos u.a. das os. Aber den Grafikchip nicht. Viele schreiben in diversen Foren das das mit Java nicht möglich sei und man bräuchte ne eigene lib dafür oder assembler, aber wenn man zugriff auf den verwendeten Speicher der VM, den Prozessorty sowie das OS bekommt, dann vermute ich, dass das mit Java auch iwie gehen sollte.
 
E

Eichelhäer

Ok interessant. Ich hab mittlewrweile zugriff auf das Win32GraphicsDevice[screen=0]. Das ist ber der Bildschirm selbst aber nicht die Grafikkarte.Vermutlich braucht man da den hashcode von der jewiligen Hardwarekomponente und übersetzt das ding in nen String. Allerdings kenn ich immernoch nicht den Befehl zum Auslesen sämtlicher eingebauter Hardware.
 
Thema: 

Auf JPanel malen und davor JComponenten anzeigen

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben