Seite 1 von 1

AWT - Diagramm mit einem Hintergrundbild

Verfasst: Do Jul 07, 2016 11:34 am
von forumnewbie
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!!!

Re: AWT - Diagramm mit einem Hintergrundbild

Verfasst: Do Jul 07, 2016 7:24 pm
von Xin
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?

Re: AWT - Diagramm mit einem Hintergrundbild

Verfasst: Do Jul 07, 2016 8:44 pm
von forumnewbie
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).

Re: AWT - Diagramm mit einem Hintergrundbild

Verfasst: Do Jul 07, 2016 9:16 pm
von Xin
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.

Re: AWT - Diagramm mit einem Hintergrundbild

Verfasst: So Jul 10, 2016 6:52 pm
von forumnewbie
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.

Re: AWT - Diagramm mit einem Hintergrundbild

Verfasst: So Jul 10, 2016 9:03 pm
von Xin
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.