AWT - Diagramm mit einem Hintergrundbild

Objektorientierte Programmiersprache auf Basis einer virtuellen Maschine (https://www.oracle.com/java/)
Antworten
forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

AWT - Diagramm mit einem Hintergrundbild

Beitrag von forumnewbie » Do Jul 07, 2016 11:34 am

Hallo!

Ich bereite mich für meine Java Prüfung vor :cry: :cry: :cry: . Eine beliebte Prüfungsfrage war ein Bild im Hintergrund anzeigen und ein Diagramm im Vordergrund erstellen. Folgende Einschränkungen gelten: Nur AWT darf verwendet werden - kein Swing oder FX und keine Drittanbieter-Bibliotheken (Standard-API Java 1.6 vermutlich).

Ich habe es nicht geschafft das Bild als ein Hintergrundbild zu machen, sodass die Diagramme auf dem Hintergrundbild liegen und sichtbar bleiben. Aktuell habe ich das Bild als ein Header-Bild gemacht. Ich habe ein Screenshot von meiner Anwendung gemacht.
Bild

Und hier ist mein Code:

Code: Alles auswählen

public class Main {
	
	public static void main(String[] args) {
		MainWindow mainWindow = new MainWindow();
	}
}

Code: Alles auswählen

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class MainWindow extends Frame{
	
	public MainWindow() {
		setIconImage(Toolkit.getDefaultToolkit().getImage("/home/user/Bilder/MaverickEyes_Favicon_Image.gif"));
		setTitle("Bild und Diagramme");
		setSize(800, 600);
					
	    double[] values = new double[3];
	    String[] names = new String[3];
	    values[0] = 1;
	    names[0] = "Item 1";

	    values[1] = 2;
	    names[1] = "Item 2";

	    values[2] = 4;
	    names[2] = "Item 3";
	    	    
	    setLayout(new GridLayout(2,1));
	    Panel top = new Panel(new FlowLayout());
	    top.add(new ImageComponent("/home/user/Bilder/dreamweaver-800x600.jpg"));	    
	    Panel content = new Panel(new GridLayout(1,2));
	    content.setBackground(Color.WHITE);
	    BarChart barChart = new BarChart(values, names, "Bar Chart");
	    barChart.setBackground(Color.WHITE);
	    content.add(barChart);
	    PieChart pieChart = new PieChart();
	    pieChart.setBackground(Color.WHITE);
	    content.add(pieChart);
	    
	    add(top);
	    add(content);

	    WindowListener wndCloser = new WindowAdapter() {
	      public void windowClosing(WindowEvent e) {
	        System.exit(0);
	      }
	    };
	    addWindowListener(wndCloser);	    
	    
		setVisible(true);
	}		
}

Code: Alles auswählen

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

class ImageComponent extends Panel {
	BufferedImage img;
	
	public void paint(Graphics g) {
		g.drawImage(img, 0, 0, null);
	}

	public ImageComponent(String path) {
		try {
			img = ImageIO.read(new File(path));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public Dimension getPreferredSize() {
		if (img == null) {
			return new Dimension(200,200);
		} else {
			return new Dimension(img.getWidth(), img.getHeight());
		}
	}
}

Code: Alles auswählen

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Panel;

public class BarChart extends Panel {
  private double[] values;

  private String[] names;

  private String title;

  public BarChart(double[] v, String[] n, String t) {
    names = n;
    values = v;
    title = t;
  }

  public void paint(Graphics g) {
    super.paint(g);
    if (values == null || values.length == 0)
      return;
    double minValue = 0;
    double maxValue = 0;
    for (int i = 0; i < values.length; i++) {
      if (minValue > values[i])
        minValue = values[i];
      if (maxValue < values[i])
        maxValue = values[i];
    }

    Dimension d = new Dimension(200,200);
    int clientWidth = d.width;
    int clientHeight = d.height;
    int barWidth = clientWidth / values.length;

    Font titleFont = new Font("SansSerif", Font.BOLD, 20);
    FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
    Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
    FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);

    int titleWidth = titleFontMetrics.stringWidth(title);
    int y = titleFontMetrics.getAscent();
    int x = (clientWidth - titleWidth) / 2;
    g.setFont(titleFont);
    g.drawString(title, x, y);

    int top = titleFontMetrics.getHeight();
    int bottom = labelFontMetrics.getHeight();
    if (maxValue == minValue)
      return;
    double scale = (clientHeight - top - bottom) / (maxValue - minValue);
    y = clientHeight - labelFontMetrics.getDescent();
    g.setFont(labelFont);

    for (int i = 0; i < values.length; i++) {
      int valueX = i * barWidth + 1;
      int valueY = top;

      int height = (int) (values[i] * scale);
      if (values[i] >= 0)
        valueY += (int) ((maxValue - values[i]) * scale);
      else {
        valueY += (int) (maxValue * scale);
        height = -height;
      }

      g.setColor(Color.red);
      g.fillRect(valueX, valueY, barWidth - 2, height);
      g.setColor(Color.black);
      g.drawRect(valueX, valueY, barWidth - 2, height);
      int labelWidth = labelFontMetrics.stringWidth(names[i]);
      x = i * barWidth + (barWidth - labelWidth) / 2;
      g.drawString(names[i], x, y);
    }
  }
}

Code: Alles auswählen

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Rectangle;

class Slice {
  double value;
  Color color;

  public Slice(double value, Color color) {
    this.value = value;
    this.color = color;
  }
}

class PieChart extends Panel {
  Slice[] slices = { new Slice(5, Color.black), new Slice(33, Color.green),
      new Slice(20, Color.yellow), new Slice(15, Color.red) };

  PieChart() {

  }
  public void paint(Graphics g) {
    drawPie((Graphics2D) g, getBounds(), slices);
  }

  void drawPie(Graphics2D g, Rectangle area, Slice[] slices) {
	area = new Rectangle(10, 10, 200, 200);
    double total = 0.0D;
    for (int i = 0; i < slices.length; i++) {
      total += slices[i].value;
    }

    double curValue = 0.0D;
    int startAngle = 0;
    for (int i = 0; i < slices.length; i++) {
      startAngle = (int) (curValue * 360 / total);
      int arcAngle = (int) (slices[i].value * 360 / total);

      g.setColor(slices[i].color);
      g.fillArc(area.x, area.y, area.width, area.height, startAngle, arcAngle);
      curValue += slices[i].value;
    }
  }
}
Könnte jemand bitte meinen Code so ändern, dass die Diagramme auf dem Bild im Vordergrund liegen und das Bild im Hintergrund (wie in HTML <body background="bgimage.jpg"> )? Ihr könnt gerne den Code vereinfachen und kürzen, wenn danach alles noch funktioniert. Ich habe anhand von Anleitungen aus dem Internet diese Anwendung erstellt.

Danke!!!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8492
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: AWT - Diagramm mit einem Hintergrundbild

Beitrag von Xin » Do Jul 07, 2016 7:24 pm

Ich habe mich gerade mal damit kurz auseinander gesetzt, das Programm kompiliert und gestartet.

Ich habe keinen Plan von Java. Ich habe das Programm so geändert, dass das Bild als Hintergrund des Frames erscheint und nicht als Panel gezeichnet wird.
Die beiden anderen Panels bekomme ich aber im Hintergrund nicht transparent, selbst, wenn ich als Background eine transparente Farbe setze.
Das Problem scheint es häufiger zu geben: Sicher, dass AWT das überhaupt kann?

Falls nicht, müssten die Panels den richtigen Teil ihres Background zeichnen, oder?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: AWT - Diagramm mit einem Hintergrundbild

Beitrag von forumnewbie » Do Jul 07, 2016 8:44 pm

Hi und danke für deine Antwort!

Ob es AWT kann, kann ich leider nicht sagen. Ich kann nur sagen, dass der Prof. immer eine AWT Anwendung haben möchte und die Frage so in einer Klausur war. Falls es Swing aber kann, könnte man vielleicht die Klasse, welche das Bild lädt, von Swing (JPanel) ableiten und sie Transparent machen? Die Hauptanwendung würde noch als AWT bleiben. Das Bild wird aber nicht wirklich im Hintergrund liegen (falls es überhaupt klappt so zu mischen).

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8492
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: AWT - Diagramm mit einem Hintergrundbild

Beitrag von Xin » Do Jul 07, 2016 9:16 pm

Mir schien, dass JPanel transparente Background können... ich habe jedenfalls mehr Ergebnisse zu JPanels gefunden, die aber ausgefiltert, weil Du ja AWT haben wolltest.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: AWT - Diagramm mit einem Hintergrundbild

Beitrag von forumnewbie » So Jul 10, 2016 6:52 pm

Ich weiß jetzt wie das geht. Hier ein einfaches Videotutorial: https://www.youtube.com/watch?v=WXVQz0ARz28 .
Zunächst das Hintergrundbild laden und dann mit der pain()-Methode an bestimmten/beliebigen Koordinaten die gewünschten geometrischen Figuren zeichnen. Es spielt dabei keine Rolle, ob es sich um eine AWT oder Swing Anwendung handelt.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8492
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: AWT - Diagramm mit einem Hintergrundbild

Beitrag von Xin » So Jul 10, 2016 9:03 pm

forumnewbie hat geschrieben:Ich weiß jetzt wie das geht. Hier ein einfaches Videotutorial: https://www.youtube.com/watch?v=WXVQz0ARz28 .
Zunächst das Hintergrundbild laden und dann mit der pain()-Methode an bestimmten/beliebigen Koordinaten die gewünschten geometrischen Figuren zeichnen. Es spielt dabei keine Rolle, ob es sich um eine AWT oder Swing Anwendung handelt.
pain()... auch hübsch.

Ich habe es mit paint() versucht, aber die AWT-Controls haben es anschließend mit ihrer Hintergrundfarbe übermalt.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten