einfache Frage:warum ist Hintergrund grau ?

ernst

Top Contributor
Hallo allerseits,
in einem Demo-Programm (mit Netbeans erstellt und dem zugehörigen grafischen Editor) lasse ich zu Testzwecken immer wieder 2 selbstgebastelte Autos (also keine Autos aus Grafikdateien) sich von von links nach rechts bewegen.
Das einfache Demo-Programm funktioniert. Nur gibt es ein kleines Problem:
Den Hintergrund habe ich im Visual-Editor (VE) in SpielJFrame rot und in SpielJPanel grün gemacht.
Warum erscheint der Hintergrund aber grau ??
Wo ist mein Fehler ?
Habe schon alles Mögliche probiert, hat aber nichts geholfen.

mfg
Ernst


[Java]
package pack30;

public class SpielJFrame extends javax.swing.JFrame {
private SpielJPanel spielJPanel;
/** Creates new form SpielJFrame */
public SpielJFrame() {
initComponents();
spielJPanel = new SpielJPanel();
jPanel1.add(spielJPanel, "Center");
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jPanel1 = new javax.swing.JPanel();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jPanel1.setBackground(new java.awt.Color(255, 204, 153));
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setLayout(new java.awt.BorderLayout());

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 217, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(85, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new SpielJFrame().setVisible(true);
}
});
}

// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
// End of variables declaration

}

[/Java]

[Java]
package pack30;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

public class SpielJPanel extends javax.swing.JPanel {
private Timer t;
private Auto auto1;
private Auto auto2;
private Image bild;
/** Creates new form SpielJPanel */
public SpielJPanel() {
initComponents();
auto1 = new Auto(this, Color.RED, 0, 0, 100);
auto2 = new Auto(this, Color.BLUE, 50, 80, 100);
auto1.setSchritt(10);
auto2.setSchritt(20);
t = new Timer(20,
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
myupdate();
maleInsBild();
repaint();
}
});

t.start();

}

public void setTimer(int millis) {
t.setDelay(millis);
}

public int getTimerTime() {
return t.getDelay();
}

public void myupdate() {
System.out.println("this.getWidth()="+this.getWidth()+"this.getHeight="+this.getHeight());
auto1.berechnePos();
auto2.berechnePos();
}

public void maleInsBild(){
int sx, sy;
Graphics graphics=null;
sx = this.getSize().width;
sy = this.getSize().height;
bild = createImage(sx, sy);
graphics = bild.getGraphics();
auto1.zeichneAuto(graphics);
auto2.zeichneAuto(graphics);
}


public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bild,0,0,null);
}



/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

setBackground(new java.awt.Color(204, 255, 153));
setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
setLayout(new java.awt.BorderLayout());
}// </editor-fold>


// Variables declaration - do not modify
// End of variables declaration

}
[/Java]


[Java]
package pack30;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;

public class Auto {
private SpielJPanel spielJPanel;
private Color farbe;
private int x;
private int y;
private int groesse;
private int schritt;
private static int strassenlaenge;

public Auto(SpielJPanel pSpielJPanel, Color pFarbe, int pOrtX, int pOrtY, int pGroesse){
spielJPanel = pSpielJPanel;
farbe = pFarbe;
x = pOrtX;
y = pOrtY;
groesse = pGroesse;
schritt = 0;
}

public void setX(int pX){
x = pX;
}

public int getX(){
return x;
}

public void setY(int pY){
y = pY;
}

public int getY(){
return y;
}

public void setFarbe(Color pFarbe){
farbe = pFarbe;
}

public Color getFarbe(){
return farbe;
}

void berechnePos(){
if(x <= spielJPanel.getWidth()){
x = x + schritt;
}
else{
x=0;
}
}

public Point getPos() {
return new Point(x, y);
}


void setSchritt(int pSchritt){
schritt = pSchritt;
}



void zeichneAuto(Graphics g){
// Linker oberer Eckpunkt des Wagens
int x1 = x;
int y1 = y;
// Rechter unterer Eckpunkt des Wagens
int x2 = x1 + groesse; // Größe = Länge = x2-ortX
int y2 = y1 + groesse/2; // Höhe = y2-ortY

// Linker oberer Eckpunkt des Fensters
int x3 = x2 - groesse/4; // Fenster
int y3 = y1;
// Rechter unterer Eckpunkt des Fensters
int x4 = x3 + groesse/4; // Fenster
int y4 = y3 + groesse/4;

int r = groesse/8; // RadRadius
int x5 = x1 + 19 + r/2; // Hinterrad
int x6 = x2 - 19 - r/2; // Vorderrad

// Karosserie
g.setColor(farbe);
g.drawRect(x1, y1, x2-x1, y2-y1);
g.fillRect(x1, y1, x2-x1, y2-y1);

// Fenster
g.setColor(Color.BLACK);
g.drawRect(x3-1, y3-1, x4-x3+1, y4-y3+1);
g.setColor(Color.WHITE);
g.fillRect(x3, y3, x4-x3, y4-y3);

// Hinterrad
g.setColor(Color.BLACK);
g.fillOval(x1, y2-r, 2*r, 2*r);

// Vorderrad
g.fillOval(x2-2*r, y2-r, 2*r, 2*r);

}
}

[/Java]
 

Marco13

Top Contributor
Hach, ich vergess' immer wieder welche Components standardmäßig Opaque sind und welche nicht. Kannst mal in die erste Zeile der initComponents
setOpaque(true);
einfügen - und wenn's hilft, schauen, wo man in diesem Visual Dingsda die "Opaque"-Checkbox anklicken kann... wenn nicht... muss man nochmal genauer schauen...
 

ernst

Top Contributor
Hach, ich vergess' immer wieder welche Components standardmäßig Opaque sind und welche nicht. Kannst mal in die erste Zeile der initComponents
setOpaque(true);
einfügen - und wenn's hilft, schauen, wo man in diesem Visual Dingsda die "Opaque"-Checkbox anklicken kann... wenn nicht... muss man nochmal genauer schauen...
In den generierten Quellcode läßt mich der Visual-Editor (VE) nicht einfügen. Ich kann also _in_ der Methode initComponents nichts einfügen.
Alternativ habe ich folgendes gemacht.
1) _Vor_ die Anweisung
initComponents();
habe ich in SpielJPanel
eingefügt:
setOpaque(true);

(In SpielJFrame läßt mich vor initComponents(); der Compiler kein setOpaque(true); einfügen; er gibt mir eine Fehlermeldung)

2)
In SpielJPanel hat der VE bei
opaque
einen Haken gemacht. Egal ob ich den Haken wegmache oder dranlasse, bekomme ich wieder einen grauen Hintergrund.

mfg
Ernst
 

Marco13

Top Contributor
Ahja, hab' nochmal genauer nachgesehen: Dass der eigentliche Mal-Bereich grau ist, liegt daran, dass dort dieses Bild gemalt wird... und das ist erstmal grau. In die maleInBild-Methode
Code:
        graphics = bild.getGraphics();
[b]
        graphics.setColor(getBackground());
        graphics.fillRect(0,0,sx,sy);
[/b]
        auto1.zeichneAuto(graphics);
behebt das schon mal, wobei es eigentlich ziemlich unschön ist, dort immer ein neues Bild zu erstellen... Besser wäre es, EINmal das Bild zu erstellen (wenn es noch null ist), und es nur neu zu erzeugen, wenn sich die Höhe oder Breite geändert hat.

Wo man das rote Panel sehen soll, erschließt sich mir aber nicht ganz... Wenn man das
jPanel1.setBackground(new java.awt.Color(255, 204, 153));
ändert in
getContentPane().setBackground(new java.awt.Color(255, 204, 153));
malt er den ganzen Hintergrund rot - kannst ja mal schauen, ob man das mit diesem Visual-Editor auch machen kann. Notfalls kann man diese Zeile aber auch im Konstruktor vom SpielJFrame einfügen.
 

ernst

Top Contributor
Ahja, hab' nochmal genauer nachgesehen: Dass der eigentliche Mal-Bereich grau ist, liegt daran, dass dort dieses Bild gemalt wird... und das ist erstmal grau. In die maleInBild-Methode
Code:
        graphics = bild.getGraphics();
[b]
        graphics.setColor(getBackground());
        graphics.fillRect(0,0,sx,sy);
[/b]
        auto1.zeichneAuto(graphics);
behebt das schon mal, wobei es eigentlich ziemlich unschön ist, dort immer ein neues Bild zu erstellen... Besser wäre es, EINmal das Bild zu erstellen (wenn es noch null ist), und es nur neu zu erzeugen, wenn sich die Höhe oder Breite geändert hat.

Wo man das rote Panel sehen soll, erschließt sich mir aber nicht ganz... Wenn man das
jPanel1.setBackground(new java.awt.Color(255, 204, 153));
ändert in
getContentPane().setBackground(new java.awt.Color(255, 204, 153));
malt er den ganzen Hintergrund rot - kannst ja mal schauen, ob man das mit diesem Visual-Editor auch machen kann. Notfalls kann man diese Zeile aber auch im Konstruktor vom SpielJFrame einfügen.

I)
Danke für den Tipp. Wenn ich diese Dinge mache:
graphics.setColor(getBackground());
graphics.fillRect(0,0,sx,sy);
und
getContentPane().setBackground(new java.awt.Color(255, 204, 153));
habe ich den roten Hintergrund im Fenster und den gelben Hintergrund auf der Zeichenfläche.
Alles funktioniert, so wie du es beschrieben hast..
II)
Um eure Geduld nicht zu strapazieren, habe ich in meinem letzten Posting aber nur das abgespeckte Problemprogramm gesendet.
In meinem wirköichen, nicht abgespeckten Problemprogram (siehe unten), habe ich den Tipp von dir auch berücksichtigt, doch bekomme ich leider nicht den entsprechenden Hintergrund auf meiner Zeichenfläche. Auch sind die Schieberegler immer noch grau.
Warum ?

PS:
Da der Quelltext sehr groß ist, schicke ich ihn in 2 Postings

[Java]

package pack1;

import java.awt.Color;
import java.util.Hashtable;
import javax.swing.JLabel;
import javax.swing.JSlider;

public class ZeichnungJFrame extends javax.swing.JFrame {
private ZeichnungJPanel zeichnungJPanel;

public ZeichnungJFrame() {
String s1, s2, s3;
initComponents();
getContentPane().setBackground(new java.awt.Color(255, 204, 153));
s1="Sekantensteigung und Tangentensteigung: ";
s2="deltaX, x-Wert des Festpunktes (mit Schieberegler) und Laufpunkt ";
s3="(mit der Maus) veränderbar";
setTitle(s1+s2+s3);
int slidermin = -100;
int slidermax = 100;
this.setSize(1000, 700);

zeichnungJPanel = new ZeichnungJPanel(this);

jPanel1.add(zeichnungJPanel, "Center");
// Maximaler Wert, den der Slider (Schieberegöler ganz links) zurückgibt
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Kaum zu glauben, aber laut Debugger ruft setMinimum() die
// Methode jSlider1.changeEvent() auf
jSlider1.setMinimum(slidermin);
jSlider1.setMaximum(slidermax);
jSlider1.setOrientation(JSlider.HORIZONTAL);
jSlider1.setPaintLabels(true);
jSlider1.setPaintTicks(true);
jSlider1.setMajorTickSpacing(10 );
Hashtable labelTable = new Hashtable();
labelTable.put(new Integer(slidermin), new JLabel(Integer.toString(slidermin/10)));
labelTable.put(new Integer(0), new JLabel("0"));
labelTable.put(new Integer(slidermax), new JLabel(Integer.toString(slidermax/10)));
jSlider1.setLabelTable(labelTable);

// Maximaler Wert, den der Slider (Schieberegöler ganz links) zurückgibt
jSlider2.setMinimum(slidermin);
jSlider2.setMaximum(slidermax);
jSlider2.setOrientation(JSlider.HORIZONTAL);
jSlider2.setPaintLabels(true);
jSlider2.setPaintTicks(true);
jSlider2.setMajorTickSpacing(10 );
Hashtable labelTable2 = new Hashtable();
labelTable2.put(new Integer(slidermin), new JLabel(Integer.toString(slidermin/10)));
labelTable2.put(new Integer(0), new JLabel("0"));
labelTable2.put(new Integer(slidermax), new JLabel(Integer.toString(slidermax/10)));
jSlider2.setLabelTable(labelTable2);

}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jPanel1 = new javax.swing.JPanel();
jSlider1 = new javax.swing.JSlider();
jSlider2 = new javax.swing.JSlider();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
tx1 = new javax.swing.JTextField();
tx2 = new javax.swing.JTextField();
jLabel5 = new javax.swing.JLabel();
jLabel6 = new javax.swing.JLabel();
jLabel7 = new javax.swing.JLabel();
jLabel8 = new javax.swing.JLabel();
tx3 = new javax.swing.JTextField();
tx4 = new javax.swing.JTextField();
tx5 = new javax.swing.JTextField();
jLabel9 = new javax.swing.JLabel();
jLabel10 = new javax.swing.JLabel();
jLabel11 = new javax.swing.JLabel();
tx6 = new javax.swing.JTextField();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jPanel1.setBackground(new java.awt.Color(204, 255, 204));
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setLayout(new java.awt.BorderLayout());

jSlider1.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
jSlider1StateChanged(evt);
}
});

jSlider2.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
jSlider2StateChanged(evt);
}
});

jLabel1.setText("delta x verändern");

jLabel2.setText("x-Wert des Festpunktes verändern");

jLabel3.setText("x-Koordinate Festpunkt");

jLabel4.setText("y-Koordinate Festpunkt");

tx1.setText("jTextField1");
tx1.setEnabled(false);

tx2.setText("jTextField2");
tx2.setEnabled(false);

jLabel5.setForeground(new java.awt.Color(255, 51, 51));
jLabel5.setText("delta y");

jLabel6.setText("--------");

jLabel7.setForeground(new java.awt.Color(0, 51, 255));
jLabel7.setText("delta x");

jLabel8.setText("=");

tx3.setForeground(new java.awt.Color(255, 51, 51));
tx3.setText("jTextField3");
tx3.setEnabled(false);

tx4.setForeground(new java.awt.Color(51, 51, 255));
tx4.setText("jTextField4");
tx4.setEnabled(false);

tx5.setText("jTextField5");
tx5.setEnabled(false);

jLabel9.setText("=");

jLabel10.setText("---------------------------------");

jLabel11.setText("-");

tx6.setText("jTextField6");
tx6.setEnabled(false);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 543, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel3)
.addGap(18, 18, 18)
.addComponent(tx1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5)
.addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel7))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel8)
.addGap(12, 12, 12)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(14, 14, 14)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(jLabel9)
.addGap(18, 18, 18)
.addComponent(tx6, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))
.addGroup(layout.createSequentialGroup()
.addComponent(tx3, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tx4, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addGroup(layout.createSequentialGroup()
.addGap(60, 60, 60)
.addComponent(tx5, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(jLabel4)
.addGap(18, 18, 18)
.addComponent(tx2, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(221, 221, 221)))
.addGap(60, 60, 60))
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, 399, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, 390, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(532, 532, 532))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addGap(5, 5, 5)
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(30, 30, 30)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 45, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(tx1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel4)
.addComponent(tx2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(39, 39, 39)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tx3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel5)
.addComponent(jLabel11)
.addComponent(tx4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel10)
.addComponent(jLabel9)
.addComponent(jLabel6)
.addComponent(jLabel8)
.addComponent(tx6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel7))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(tx5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(2, 2, 2)))
.addGap(43, 43, 43))
);

pack();
}// </editor-fold>

private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {
String str;
int wert;
double dWert;
wert = jSlider1.getValue();
dWert = wert / 10.0;
zeichnungJPanel.setParameterDeltaX(dWert);
zeichnungJPanel.allesUpdaten();
zeichnungJPanel.maleKomplettesFenster();

}

private void jSlider2StateChanged(javax.swing.event.ChangeEvent evt) {
String str;
int wert;
double dWert;
wert = jSlider2.getValue();
dWert = wert / 10.0;

zeichnungJPanel.setParameterXFestpunkt(dWert);
zeichnungJPanel.allesUpdaten();
zeichnungJPanel.maleKomplettesFenster();

}


public void maleRestZeichnungJFrame(){
String str;
float ergebnis;
double xFestpunkt, yFestpunkt, xLaufpunkt, yLaufpunkt, erg;
xFestpunkt = zeichnungJPanel.getTangente().getFestPunkt().x;
yFestpunkt = zeichnungJPanel.getTangente().getFestPunkt().y;
xLaufpunkt = zeichnungJPanel.getTangente().getLaufPunkt().x;
yLaufpunkt = zeichnungJPanel.getTangente().getLaufPunkt().y;

int sliderwert;
/* A C H T U N G:
sliderwert=(int)((xLaufpunkt-xFestpunkt)*10);
lieferte
xLaufpunkt-xFestpunkt==2.9999999999999996 und damit
sliderwert=29
D E S W E G EN die folgende Konstruktion
*/
ergebnis=(float)((xLaufpunkt-xFestpunkt)*10);
sliderwert=Math.round(ergebnis);
jSlider1.setValue(sliderwert);

sliderwert=(int)(xFestpunkt*10);
jSlider2.setValue(sliderwert);

str = new String(String.valueOf(xFestpunkt));
tx1.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(yFestpunkt));
tx2.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(yLaufpunkt));
tx3.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(yFestpunkt));
tx4.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(xLaufpunkt-xFestpunkt));
tx5.setText(str.substring(0,str.length()<6?str.length():5));

String s;
if (xLaufpunkt-xFestpunkt==0)
s="nicht definiert";
else{
erg = (yLaufpunkt-yFestpunkt)/(xLaufpunkt-xFestpunkt);
str = new String(String.valueOf(erg));
s = str.substring(0,str.length()<6?str.length():5);
}
tx6.setText(s);
}


public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
ZeichnungJFrame zeichnungJFrame = new ZeichnungJFrame();
zeichnungJFrame.setVisible(true);
zeichnungJFrame.zeichnungJPanel.setParameterDeltaX(3);
zeichnungJFrame.zeichnungJPanel.setParameterXFestpunkt(1);
zeichnungJFrame.zeichnungJPanel.allesUpdaten();
zeichnungJFrame.zeichnungJPanel.maleKomplettesFenster();


}
});
}

// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;
private javax.swing.JLabel jLabel11;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JPanel jPanel1;
private javax.swing.JSlider jSlider1;
private javax.swing.JSlider jSlider2;
private javax.swing.JTextField tx1;
private javax.swing.JTextField tx2;
private javax.swing.JTextField tx3;
private javax.swing.JTextField tx4;
private javax.swing.JTextField tx5;
private javax.swing.JTextField tx6;
// End of variables declaration

}
[/Java]



mfg
Ernst
 

ernst

Top Contributor
Ahja, hab' nochmal genauer nachgesehen: Dass der eigentliche Mal-Bereich grau ist, liegt daran, dass dort dieses Bild gemalt wird... und das ist erstmal grau. In die maleInBild-Methode
Code:
        graphics = bild.getGraphics();
[b]
        graphics.setColor(getBackground());
        graphics.fillRect(0,0,sx,sy);
[/b]
        auto1.zeichneAuto(graphics);
behebt das schon mal, wobei es eigentlich ziemlich unschön ist, dort immer ein neues Bild zu erstellen... Besser wäre es, EINmal das Bild zu erstellen (wenn es noch null ist), und es nur neu zu erzeugen, wenn sich die Höhe oder Breite geändert hat.

Wo man das rote Panel sehen soll, erschließt sich mir aber nicht ganz... Wenn man das
jPanel1.setBackground(new java.awt.Color(255, 204, 153));
ändert in
getContentPane().setBackground(new java.awt.Color(255, 204, 153));
malt er den ganzen Hintergrund rot - kannst ja mal schauen, ob man das mit diesem Visual-Editor auch machen kann. Notfalls kann man diese Zeile aber auch im Konstruktor vom SpielJFrame einfügen.

Hier ist der Rest:

[Java]
package pack1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;


public class ZeichnungJPanel extends javax.swing.JPanel implements MouseListener, MouseMotionListener {
ZeichnungJFrame zeichnungJFrame;
private Image bild;
private Tangente tangente;
private double parameterDeltaX;
private double parameterxFestpunkt;
private Graphics graphicsNormalparabel;
private Image bildNormalparabel;
private int flag = 0;

private int mausBewegt;


public ZeichnungJPanel(ZeichnungJFrame pZeichnungJFrame) {
initComponents();
zeichnungJFrame = pZeichnungJFrame;
mausBewegt = 0;
tangente = new Tangente(this);
addMouseMotionListener(this);
addMouseListener(this);
parameterDeltaX=3;
parameterxFestpunkt=1;

}

public Tangente getTangente(){
return tangente;
}

public void setParameterXFestpunkt(double pParameterxFestpunkt){
parameterxFestpunkt = pParameterxFestpunkt;
}

public double getParameterXFestpunkt(){
return parameterxFestpunkt;
}

public void setParameterDeltaX(double pDeltaX){
parameterDeltaX = pDeltaX;
}

public double getParameterDeltaX(){
return parameterDeltaX;
}

public void allesUpdaten() {
tangente.berechnePos();
}

public void maleKomplettesFenster(){
maleZeichnungJPanelOffscreen();
zeichnungJFrame.maleRestZeichnungJFrame();
repaint();
}


public void maleZeichnungJPanelOffscreen(){
int sx, sy;
Graphics graphics=null;

sx = this.getSize().width;
sy = this.getSize().height;
if(sx!=0 && sy!=0){
bild = createImage(sx, sy);
graphics = bild.getGraphics();
graphics.setColor(getBackground());
graphics.fillRect(0,0,sx,sy);


Transformation.setBreite(sx);
Transformation.setHoehe(sy);
tangente.zeichneNormalparabel(graphics, Color.black);
tangente.zeichneSekante(graphics, Color.green);
tangente.zeichneTangente(graphics, Color.cyan);
tangente.zeichneAchsenkreuz(graphics, Color.black);
}
}


public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bild,0,0,Color.white,null);

}

public void mouseClicked(MouseEvent arg0) {
}

public void mousePressed(MouseEvent arg0) {
}

public void mouseEntered(MouseEvent arg0) {
}

public void mouseExited(MouseEvent arg0) {
}

public void mouseMoved(MouseEvent arg0) {
}

public void mouseDragged(MouseEvent ev) {
boolean b;
Point klick = new Point();
klick = ev.getPoint();
b = tangente.istInnerhalb(klick, tangente.getLaufPunkt());
if(b==true){
if(mausBewegt==0){
mausBewegt=1;
}

}
}

public void mouseReleased(MouseEvent ev) {
boolean b;
Point javaklick = new Point();
Point2DDouble p2D;


javaklick = ev.getPoint();

if(mausBewegt==1){
mausBewegt=0;
b = tangente.punktAufKurve(javaklick);

if(b==true){
p2D = Transformation.transformJavaTo2D(javaklick.x, javaklick.y);
setParameterDeltaX(p2D.x-tangente.getFestPunkt().x);
allesUpdaten();
maleKomplettesFenster();
}

}
}


/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

setBackground(new java.awt.Color(255, 255, 204));

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 523, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 312, Short.MAX_VALUE)
);
}// </editor-fold>


// Variables declaration - do not modify
// End of variables declaration

}
[/Java]

[Java]
package pack1;

public class Point2DDouble {
public double x;
public double y;

public Point2DDouble(double px, double py) {
x = px;
y = py;
}
}

[/Java]

[Java]
package pack1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JLabel;

public class Tangente{
private ZeichnungJPanel zeichnungJPanel;
private Point2DDouble festPunkt;
private Point2DDouble laufPunkt;
private Image bildNormalparabel;
private int flag;
// Halbe Dicke eines Punktes auf dem Bildschirm
private double abstand;

public Tangente(ZeichnungJPanel pZeichnungJPanel){
zeichnungJPanel = pZeichnungJPanel;
festPunkt = new Point2DDouble(0,0);
laufPunkt = new Point2DDouble(0,0);
flag = 0;
abstand = 0.1;
}

public void setFestPunkt(double px, double py){
festPunkt.x = px;
festPunkt.y = py;
}

public Point2DDouble getFestPunkt(){
return(festPunkt);
}

public void setLaufPunkt(double px, double py){
laufPunkt.x = px;
laufPunkt.y = py;
}

public Point2DDouble getLaufPunkt(){
return(laufPunkt);
}

public void berechnePos(){
double parameterDeltaX, parameterXFestpunkt;
parameterDeltaX = zeichnungJPanel.getParameterDeltaX();
parameterXFestpunkt = zeichnungJPanel.getParameterXFestpunkt();
festPunkt.x = parameterXFestpunkt;
festPunkt.y = festPunkt.x * festPunkt.x;

laufPunkt.x = festPunkt.x + parameterDeltaX;
laufPunkt.y = laufPunkt.x * laufPunkt.x;

}

public void zeichneSekante(Graphics g, Color farbe){
double x1, y1, x2, y2;

x1 = laufPunkt.x;
y1 = laufPunkt.y;
x2 = laufPunkt.x;
y2 = festPunkt.y;
g.setColor(Color.red);
drawLineReal(g, x1, y1, x2, y2);
drawPunktReal(g, Color.magenta, festPunkt.x, festPunkt.y);
drawPunktReal(g, Color.pink, laufPunkt.x, laufPunkt.y);


x1 = festPunkt.x;
y1 = festPunkt.y;
x2 = laufPunkt.x;
y2 = festPunkt.y;
g.setColor(Color.blue);
drawLineReal(g, x1, y1, x2, y2);



x1=Transformation.minX;
y1=(laufPunkt.y-festPunkt.y)/(laufPunkt.x-festPunkt.x)*(x1-festPunkt.x)+festPunkt.y;

x2=Transformation.maxX;
y2=(laufPunkt.y-festPunkt.y)/(laufPunkt.x-festPunkt.x)*(x2-festPunkt.x)+festPunkt.y;
g.setColor(farbe);
drawLineReal(g, x1, y1, x2, y2);
}

public void zeichneTangente(Graphics g, Color farbe){
double xBeginn, xEnde, yBeginn, yEnde;
g.setColor(farbe);
xBeginn = Transformation.minX;
xEnde = Transformation.maxX;
yBeginn = 2*festPunkt.x*(xBeginn-festPunkt.x)+ festPunkt.y;
yEnde = 2*festPunkt.x*(xEnde-festPunkt.x)+ festPunkt.y;
drawLineReal(g, xBeginn, yBeginn, xEnde, yEnde);
}

public void zeichneAchsenkreuz(Graphics g, Color farbe){
Point2DDouble A2D = new Point2DDouble(0,0);
Point2DDouble B2D = new Point2DDouble(0,0);

g.setColor(farbe);
A2D.x = Transformation.minX;
A2D.y = 0;
B2D.x = Transformation.maxX;;
B2D.y = 0;
drawLineReal(g, A2D.x, A2D.y, B2D.x, B2D.y);
drawDreieckReal(g, Color.black, B2D.x, B2D.y, B2D.x-0.2, B2D.y+0.2, B2D.x-0.2, B2D.y-0.2);
beschrifteAchsenkreuz(g, farbe);

A2D.x = 0;
A2D.y = Transformation.minY;
B2D.x=0;
B2D.y=Transformation.maxY;
drawLineReal(g, A2D.x, A2D.y, B2D.x, B2D.y);
drawDreieckReal(g, Color.black, B2D.x, B2D.y, B2D.x-0.2, B2D.y-0.2, B2D.x+0.2, B2D.y-0.2);
}

public void beschrifteAchsenkreuz(Graphics g, Color farbe){
double min, max, x, y;
min = Transformation.minX;
max = Transformation.maxX;
x=0;
do{
drawLineReal(g, x, 0.1, x, -0.1);
x=x+1;
}
while (x<=max);

x=0;
do{
drawLineReal(g, x, 0.1, x, -0.1);
x=x-1;
}
while (x>=min);

min = Transformation.minY;
max = Transformation.maxY;
y=0;
do{
drawLineReal(g, -0.1, y, 0.1, y);
y=y+1;
}
while (y<=max);

do{
drawLineReal(g, -0.1, y, 0.1, y);
y=y-1;
}
while (y>=min);


}




public void zeichneNormalparabel(Graphics g, Color farbe){
int sx, sy;
Graphics graphicsNormalparabel = null;
Point2DDouble P = new Point2DDouble(0,0);
Point PJava;
double schrittbreite;

g.setColor(farbe);
sx = zeichnungJPanel.getSize().width;
sy = zeichnungJPanel.getSize().height;

if(flag==0){
while (sx==0 && sy==0){
}
flag=1;
bildNormalparabel = zeichnungJPanel.createImage(sx, sy);
graphicsNormalparabel = bildNormalparabel.getGraphics();
schrittbreite = (Transformation.maxX-Transformation.minX)/10000;

P.x = Transformation.minX;
while(P.x<Transformation.maxX){
PJava = Transformation.transform2DToJava(P.x, P.y);
graphicsNormalparabel.drawLine(PJava.x, PJava.y, PJava.x+0, PJava.y+0);
P.x = P.x+ schrittbreite;
P.y=P.x*P.x;
}
}
g.drawImage(bildNormalparabel,0,0,null);
}


public void drawLineReal(Graphics g, double x1, double y1, double x2, double y2){
Point A2DJava, B2DJava;
A2DJava = Transformation.transform2DToJava(x1, y1);
B2DJava = Transformation.transform2DToJava(x2, y2);
g.drawLine(A2DJava.x, A2DJava.y, B2DJava.x, B2DJava.y);
}


public void drawDreieckReal(Graphics g, Color farbe, double x1, double y1, double x2, double y2, double x3, double y3){
Point A2DJava, B2DJava, C2DJava;
g.setColor(farbe);
A2DJava = Transformation.transform2DToJava(x1, y1);
B2DJava = Transformation.transform2DToJava(x2, y2);
C2DJava = Transformation.transform2DToJava(x3, y3);

int[] xPoints = new int[3];
int[] yPoints = new int[3];
xPoints[0]=A2DJava.x;
xPoints[1]=B2DJava.x;;
xPoints[2]=C2DJava.x;
yPoints[0]=A2DJava.y;
yPoints[1]=B2DJava.y;
yPoints[2]=C2DJava.y;


g.fillPolygon(xPoints, yPoints, 3);
}

public void drawPunktReal(Graphics g, Color farbe, double x, double y){
int javaAbstand;
double xobenlinks, yobenlinks, xuntenrechts, yuntenrechts;
Point A2DJava, B2DJava;
g.setColor(farbe);

xobenlinks = x - abstand;
yobenlinks = y + abstand;
xuntenrechts = x + abstand;
yuntenrechts = y - abstand;

A2DJava = Transformation.transform2DToJava(xobenlinks, yobenlinks);
B2DJava = Transformation.transform2DToJava(xuntenrechts, yuntenrechts);
javaAbstand = B2DJava.x -A2DJava.x;

g.fillOval(A2DJava.x, A2DJava.y,javaAbstand, javaAbstand );
}




public boolean istInnerhalb(Point pJavaklick, Point2DDouble p2D){
boolean b;
double x,y;
int javaAbstand;
double xobenlinks, yobenlinks, xuntenrechts, yuntenrechts;
int xobenlinksJava, yobenlinksJava, xuntenrechtsJava, yuntenrechtsJava;
Point A2DJava, B2DJava;
x = p2D.x;
y = p2D.y;

xobenlinks = x - abstand;
yobenlinks = y + abstand;
xuntenrechts = x + abstand;
yuntenrechts = y - abstand;

A2DJava = Transformation.transform2DToJava(xobenlinks, yobenlinks);
B2DJava = Transformation.transform2DToJava(xuntenrechts, yuntenrechts);
xobenlinksJava = A2DJava.x;
yobenlinksJava = A2DJava.y;
xuntenrechtsJava = B2DJava.x;
yuntenrechtsJava = B2DJava.y;

b=pJavaklick.x>xobenlinksJava && pJavaklick.x<xuntenrechtsJava && pJavaklick.y>yobenlinksJava && pJavaklick.y<yuntenrechtsJava;
return b;

}


public boolean punktAufKurve(Point pJavaklick){
boolean b;
int genauigkeit;
Point2DDouble p2D;
double x2DExakt, y2DExakt;

genauigkeit = 3;
p2D = Transformation.transformJavaTo2D(pJavaklick.x, pJavaklick.y);
x2DExakt = p2D.x;
y2DExakt = p2D.x*p2D.x;
System.out.println("x2DExakt="+x2DExakt+"y2DExakt="+y2DExakt);
b = p2D.y > y2DExakt - genauigkeit && p2D.y < y2DExakt + genauigkeit;
return b;
}


}
[/Java]

[Java]
package pack1;

import java.awt.Point;

public class Transformation {
private static double hoehe;
private static double breite;
public static double maxX;
public static double maxY;
public static double minX;
public static double minY;

public static double e;

// statischer Konstruktor
static {
// Anzahl der Pixel für den Einheitswert
e=30;
}

public static void setBreite(double pb){
breite = pb;
maxX = 0.75*breite/e;
minX = -0.25*breite/e;
}

public static void setHoehe(double ph){
hoehe = ph;
maxY = 0.95*hoehe/e;
minY = -0.05*hoehe/e;
}


public static Point transform2DToJava(double x, double y){
double xJava, yJava;
xJava = breite/4.0 + x*e;
yJava = 0.95*hoehe - y*e;
return(new Point((int)xJava, (int)yJava));
}


public static Point2DDouble transformJavaTo2D(int xJava, int yJava){
double x, y;
x = (xJava - breite/4.0)/e;
y = (0.95*hoehe - yJava)/e;
return(new Point2DDouble(x, y));
}
}
[/Java]

mfg
Ernst
 

Marco13

Top Contributor
Ich mag ja diese GUI-Builder nicht... Und als ich den Code so stückchenweise rauskopiert habe, wurde mir wieder klar, warum... bei einigen Codestellen hab' ich mir dann gedacht ... "Ohje..." :noe: (und denke das teilweise immernoch) aber....

... wenn man das dann startet, sieht's richtig cool aus :toll:

Meine ... Verwirrung in bzeug auf "setOpaque" hatte einen Grund: JSlider SIND opak, d.h. man muss an einer geeigneten Stelle noch
Code:
        jSlider1.setOpaque(false);
        jSlider2.setOpaque(false);
aufrufen.


Dass der Hintergrund der Parabel grau ist, liegt wieder an einem Bild, das den eigentlichen Hintergrund übermalt... diesmal in der Methode "zeichneNormalparabel"... dort muss noch sowas wie
Code:
            graphicsNormalparabel.setColor(zeichnungJPanel.getBackground());
            graphicsNormalparabel.fillRect(0,0,sx,sy);
            graphicsNormalparabel.setColor(farbe);
rein...

Nochmal: Insgesamt schon ein hübsches Programm :applaus: (... von "überflüssigen" Images, die erzeugt werden, dem GUI-Builder-Quälcode und solchen "magischen" Zeilen wie [c]y = (0.95*hoehe - yJava)/e;[/c] mal abgesehen... ;) )
 

ernst

Top Contributor
Ich mag ja diese GUI-Builder nicht... Und als ich den Code so stückchenweise rauskopiert habe, wurde mir wieder klar, warum... bei einigen Codestellen hab' ich mir dann gedacht ... "Ohje..." :noe: (und denke das teilweise immernoch) aber....

... wenn man das dann startet, sieht's richtig cool aus :toll:

Meine ... Verwirrung in bzeug auf "setOpaque" hatte einen Grund: JSlider SIND opak, d.h. man muss an einer geeigneten Stelle noch
Code:
        jSlider1.setOpaque(false);
        jSlider2.setOpaque(false);
aufrufen.


Dass der Hintergrund der Parabel grau ist, liegt wieder an einem Bild, das den eigentlichen Hintergrund übermalt... diesmal in der Methode "zeichneNormalparabel"... dort muss noch sowas wie
Code:
            graphicsNormalparabel.setColor(zeichnungJPanel.getBackground());
            graphicsNormalparabel.fillRect(0,0,sx,sy);
            graphicsNormalparabel.setColor(farbe);
rein...

Nochmal: Insgesamt schon ein hübsches Programm :applaus: (... von "überflüssigen" Images, die erzeugt werden, dem GUI-Builder-Quälcode und solchen "magischen" Zeilen wie [c]y = (0.95*hoehe - yJava)/e;[/c] mal abgesehen... ;) )

Danke für deine Mühe, Aufwand und Hilfe.
Es funktioniert jetzt, so wie du es gesagt hast.

1)
jSlider1.setOpaque(false);
jSlider2.setOpaque(false);
bedeutet doch optisch (im Gegenbsatz zu jSlider1.setOpaque(true); jSlider2.setOpaque(true);)
mache jSlider1 und jSlider2 nicht opak, also nicht undurchsichtig, also transparent.
Ich habe das gemacht. Optisch heißt das, daß alles direkt um den "eigentlichen" Slider herum die Hintergrundfarbe annimmt.
Nur der eigentliche Slider selbst behält seine Farbe.
Wie ist das allgemein, wenn man opak auf false setzt. Wer legt genau fest, wie das dann konkret auszusehen hat?

2)
Ich habe den Hintgrund jetzt mit VE auf weiß gesetzt (255,255,255).
Aber mir kommt es nicht ganz 100% weiß vor:
Ich meine, daß das weiß im Windows-Malprogramm paint etwas weißer ist. Aber ich kann mich auch täuschen (optische Täuschung).
Was meinst du dazu ?

mfg
Ernst
 

Marco13

Top Contributor

Nur der eigentliche Slider selbst behält seine Farbe.
Wie ist das allgemein, wenn man opak auf false setzt. Wer legt genau fest, wie das dann konkret auszusehen hat?


Das genaue Aussehen wird vom Look-And-Feel bestimmt (siehe z.B. auch How to Set the Look and Feel (The Java™ Tutorials > Creating a GUI With JFC/Swing > Modifying the Look and Feel) ). Teilweise kann man auch noch die Farben von einzelnen Elementen (wie etwa dem Slider-Knopf) festlegen, aber das ist alles nich offiziell Teil der API, und könnte bei anderen L&Fs nicht funktionieren...



Ich habe den Hintgrund jetzt mit VE auf weiß gesetzt (255,255,255).
Aber mir kommt es nicht ganz 100% weiß vor:
Ich meine, daß das weiß im Windows-Malprogramm paint etwas weißer ist.


Warum muss ich gerade an Waschmittelwerbung denken? :D Im Zweifelsfall kannst du ja einen Screenshot machen, und es in einem Malprogramm vergleichen....
 

ernst

Top Contributor
Code:
        graphics = bild.getGraphics();
[b]
        graphics.setColor(getBackground());
        graphics.fillRect(0,0,sx,sy);
[/b]
        auto1.zeichneAuto(graphics);
behebt das schon mal, wobei es eigentlich ziemlich unschön ist, dort immer ein neues Bild zu erstellen... Besser wäre es, EINmal das Bild zu erstellen (wenn es noch null ist), und es nur neu zu erzeugen, wenn sich die Höhe oder Breite geändert hat.
1)
Ich erstelle das Bild immer neu, weil bei jeder Veränderung durch die Slider bzw.das Verschieben des Laufpunkts sich auch die Zeichnung (Tangente, Sekante, Laufpunkt, Festpunkt) ändern muss.
Habe ich da einen Denkfehler?

2)
Ausnahme: Die Normalparabel. Diese lasse ich genau einmal in ein Image zeichnen, das ich dann immer wieder benutze (und nicht neu erstelle). Der Grund dafür, ist dass die Normalparabel nicht geändert wird und weil es sehr viel Zeit braucht, diese immer wieder neu zu zeichnen.
Habe ich da einen Denkfehler?

3)
Allerdings habe ich schon Programme gesehen, bei denen mit dem Schieberegler ein Parameter verändert wird und dann sofort die neue Kurve gezeichnet wird:
Beispiel: f(x) = a*x^2
Frage: Wie kann ich das in Java machen, ohne dass ich Laufzeitprobleme bekomme, dh. dass ich zwar den Schieberegler verändere, aber auch die Zeichnung sofort aktualisiert wird (dem aktuelle Parameter angepassst wird) ?

mfg
Ernst
 

Marco13

Top Contributor
Ich erstelle das Bild immer neu, weil bei jeder Veränderung durch die Slider bzw.das Verschieben des Laufpunkts sich auch die Zeichnung (Tangente, Sekante, Laufpunkt, Festpunkt) ändern muss.
Habe ich da einen Denkfehler?


Jein. Ein Bild zu erstellen ist vegleichsweise aufwändig - da muss Speicher allokiert und gecleart werden und so - und wenn es dann einmal verwendet wurde, wird es ja jetzt auf den Müll geworfen. OB man sich überhaupt die Arbeit mit diesem Offscreen-Bild machen sollte, und ob man nicht einfach das zeichnen sollte, was man zeichnen will (und zwar in das Graphics, das an die paintComponent übergeben wird) sollte man sich auch überlegen. Es gibt nicht sooo viele Fälle, wo so ein Offscreen-Bild Sinn macht. Aber WENN man eins verwendet, wäre es eben sinnvoller (und effizienter) GROB sowas zu machen wie
Java:
private BufferedImage offscreenImage = null;

public void paintStuff(...)
{

    // NUR wenn das Image noch nicht existiert, oder sich
    // die Größe geändert hat, wird ein neues angelegt
    if (offscreenImage == null || 
        offscreenImage.getWidth() != getWidth() 
        offscreenImage.getHeight() != getHeight() 
    {
        offscreenImage = ... erstellen ...
    }

    // Hier wird nur der Bildhintergrund gelöscht
    Graphics g = offscreenImage.getGraphics();
    g.setColor(Color.GREEN);
    g.fillRect(0,0,getWidth(),getHeight());
    ....
}

Wenn man eine Mischung hat, d.h. ein Teil, der aufwändig zu zeichnen ist, und der in einem Offscreen-Bild liegen soll, und einen anderen Teil, der einfach zu zeichnen ist, und NICHT in einem Offscreen-Bild liegen soll, kann es etwas kniffliger werden, das vernünftig zu "verwalten"... In diesem Fall wäre das aber IMHO eigentlich auch nicht nötig...:


Ausnahme: Die Normalparabel. Diese lasse ich genau einmal in ein Image zeichnen, das ich dann immer wieder benutze (und nicht neu erstelle). Der Grund dafür, ist dass die Normalparabel nicht geändert wird und weil es sehr viel Zeit braucht, diese immer wieder neu zu zeichnen.
Habe ich da einen Denkfehler?


Jein. So eine Parabel/Funktion kann relativ viel Zeit beanspruchen. Wichtig sind dabei die Worte "kann" und "relativ". Wenn man komplexere Funktionen zeichnen will, und sich vorstellt, man hätte z.B. eine Funktion wie
Code:
f(x) = sin(x)+tan(x)*cos(cos(cos(x))) + ackermann(x,3) + factorial(x) + busyBeaver(sin(x)*pow(10,x));
wo allein eine Auswertung der Funktion 10 Minuten dauert, dann wollte man das natürlich nicht bei jedem Neuzeichnen 1000000 mal machen - insbesondere, wenn sich nichts ändert. Spätestens, wenn man die Funktion durch verschieben eines Sliders ändern will, muss man sie aber sowieso schnell ausrechnen können. Ob man sich DANN noch unterschiedliche Behandlungen für die Fälle überlegt...
- es wird die Funktion geändert
- es wird nur eine Tangente (oder so) geändert
... müßte man sich noch überlegen.

Ganz allgemein dürfte ein Problem bei der aktuellen Implementierung aber in dieser Zeile stecken:
Code:
schrittbreite = (Transformation.maxX-Transformation.minX)/10000;
Diese 10000 ist ja vollkommen willkürlich gewählt. Und wenn man z.B. den Bereich zwischen -1000000 und +1000000 plotten wollte, wäre der Wert auch vollkommen "falsch".

Sinnvoller wäre es, genau das zu machen, was gemacht werden muss: Man kann ja nicht mehr Punkte (in x-Richtung) haben, als es Pixel auf dem Bildschirm gibt ;) In diesem Fall könnte man also sowas machen wie
Java:
int xs = 0; // Position in Screen-Koordinaten
int ys = 0; // Position in Screen-Koordinaten
double xw = 0; // Position in "Weltkoordinaten"
double yw = 0; // Position in "Weltkoordinaten"
// (Die Umrechnungen zwischen diesen Koordinatensystemen
// sind ja schon schön in der Transformation-Klasse gekapselt -
// wobei ich DRINGENDST empfehlen würde, zu versuchen, dort
// diese magischen Konstanten wie 30 und 0.95 und so rauszunehmen...)

for (xs=0; xs<breiteInPixeln; xs++)
{
    xw = Transoformation.screeenToWorldX(xs);
    yw = funktionAuswerten(xw); // Die Parabel oder sonstwas...
    ys = Transoformation.worldToScreenY(yw);

    drawLineTo(xs,ys);
}

Das ist nur Pseudocode - man müßte die Positionen für x=0 speichern dann die Schleife bei 1 loslaufen lassen, und immer sowas wie
Code:
drawLine(previousX, previousY, xs,ys);
previousX = xs;
previousY = ys;
machen... aber vom Ansatz her: Man rechnet die (sehr wenigen!) Pixel in Weltkoordinaten um, berechnet den Funktionswert dafür, und DEN rechnet man dann wieder zurück in Pixelkoordinaten.

Hier wäre auch ein Ansatzpunkt für eine Optimierung, FALLS das Auswerten der Funktion extrem aufwändig wäre: Man könnte einen
Code:
double yWorldValues[] = new double[bildBreiteInPixeln];

// oder int yScreenValues[] = new int[bildBreiteInPixeln];
// oder Point screenPoints[] = ...
// oder Point2D worldPoints[] = ...
erstellen, der die EINmal ausgrechneten Funktionswerte (als Welt- oder Screenkoordinaten) speichert, und beim Zeichnen nurnoch durch den Array läuft und den Graph für die vorberechneten Werte malt.

Genaugenommen "sollte" man sowas auch machen, weil man in der paint-Methode eigentlich so wenig wie möglich rechnen, sondern eigentlich NUR zeichnen sollte - aber man muss sich erstmal geeignete Strukturen und update-Mechanismen für diesen Werte-Array überlegen - für die Normalparabel kann man eine Berechnung in der paint-Methode wohl noch vertreten, aber du kannst ja mal weiter drüber nachdenken... Speziell auch in bezug auf den nächsten Punkt:



Allerdings habe ich schon Programme gesehen, bei denen mit dem Schieberegler ein Parameter verändert wird und dann sofort die neue Kurve gezeichnet wird:
Beispiel: f(x) = a*x^2
Frage: Wie kann ich das in Java machen, ohne dass ich Laufzeitprobleme bekomme, dh. dass ich zwar den Schieberegler verändere, aber auch die Zeichnung sofort aktualisiert wird (dem aktuelle Parameter angepassst wird) ?


Das ist ja oben schon angedeutet ;) Ich glaube, einer der wichtigsten Punkte ist, die Funktion nur an den (Welt)koordinaten auszuwerten, die den Pixelpositionen entsprechen. Damit geht das ganze schon sehr flott. (Eigentlich auch für komplizierte Funktionen - dass man in der paint-Methode nicht so viel rechnen sollte, könnte man da schon fast als eine "Prinzipsache" bezeichnen...)
 
Zuletzt bearbeitet:

ernst

Top Contributor
Ich glaube, einer der wichtigsten Punkte ist, die Funktion nur an den (Welt)koordinaten auszuwerten, die den Pixelpositionen entsprechen. Damit geht das ganze schon sehr flott. (Eigentlich auch für komplizierte Funktionen - dass man in der paint-Methode nicht so viel rechnen sollte, könnte man da schon fast als eine "Prinzipsache" bezeichnen...)

Habe deine wertvollen Tipps berücksichtigt (siehe Programm unten)

1) Wenn ich BufferedImage benutzte (statt Image) sagt mir der Compiler, dass er createImage nicht kennt.
Was kann ich machen, damit er das kennt?

2) Kann ich statt BufferedImage auch Image benutzen (so wie in meinem Programm), oder welche Nachteile hole ich mir mit Image statt BuffereImage ?

3)
Wenn ich die Parabel nur einmal zeichne, unten öfters mal das Fenster verkleiner und vergrößere und dabei den unteren Schieberegler verstelle, wird meine Parabel manchmal etwas verschoben.
An was liegt das?
Wie kann ich es ändern (ohne dass ich die Parabel jedesmal neu zeichne) ?

4)
Ist deiner Meinung nach der Hintergrund wirklich weiss?

Bem: Rest des Programm ist im nächsten Posting

mfg
Ernst

[Java]
package pack1;

public class Point2DDouble {
public double x;
public double y;

public Point2DDouble(double px, double py) {
x = px;
y = py;
}
}
[/Java]


[Java]
package pack1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JLabel;

public class Tangente{
private ZeichnungJPanel zeichnungJPanel;
private Point2DDouble festPunkt;
private Point2DDouble laufPunkt;
private Image bildNormalparabel;
private int flag;
// Halbe Dicke eines Punktes auf dem Bildschirm
private double abstand;

public Tangente(ZeichnungJPanel pZeichnungJPanel){
zeichnungJPanel = pZeichnungJPanel;
festPunkt = new Point2DDouble(0,0);
laufPunkt = new Point2DDouble(0,0);
flag = 0;
abstand = 0.1;
}

public void setFestPunkt(double px, double py){
festPunkt.x = px;
festPunkt.y = py;
}

public Point2DDouble getFestPunkt(){
return(festPunkt);
}

public void setLaufPunkt(double px, double py){
laufPunkt.x = px;
laufPunkt.y = py;
}

public Point2DDouble getLaufPunkt(){
return(laufPunkt);
}

public void berechnePos(){
// Parameter deltaX holen
double parameterDeltaX, parameterXFestpunkt;
parameterDeltaX = zeichnungJPanel.getParameterDeltaX();
//System.out.println("parameterDeltaX=="+parameterDeltaX);
parameterXFestpunkt = zeichnungJPanel.getParameterXFestpunkt();
festPunkt.x = parameterXFestpunkt;
//System.out.println("festPunkt.x=="+festPunkt.x);
festPunkt.y = festPunkt.x * festPunkt.x;
//System.out.println("festPunkt.x="+festPunkt.x);

laufPunkt.x = festPunkt.x + parameterDeltaX;
laufPunkt.y = laufPunkt.x * laufPunkt.x;
//System.out.println("laufPunkt.x="+laufPunkt.x+" laufPunkt.y"+laufPunkt.y);
}

public void zeichneSekante(Graphics g, Color farbe){
//Java-Koordinaten Festpunkt und Laufpunkt
//Einheitswert:
double x1, y1, x2, y2;
// Zeichne delta y
x1 = laufPunkt.x;
y1 = laufPunkt.y;
x2 = laufPunkt.x;
y2 = festPunkt.y;
//g.drawLine(anfangPunktJava.x, anfangPunktJava.y, endPunktJava.x, endPunktJava.y);
g.setColor(Color.red);
drawLineReal(g, x1, y1, x2, y2);
drawPunktReal(g, Color.magenta, festPunkt.x, festPunkt.y);
drawPunktReal(g, Color.darkGray, laufPunkt.x, laufPunkt.y);

// Zeichne delta x
x1 = festPunkt.x;
y1 = festPunkt.y;
x2 = laufPunkt.x;
y2 = festPunkt.y;
g.setColor(Color.blue);
drawLineReal(g, x1, y1, x2, y2);


/* Sekandengleichung berechnen:
y = (yL-yF)/(xL-xF)*(x-xF)+yF
*/
// Zeichne Gerade
x1=Transformation.wMinX;
y1=(laufPunkt.y-festPunkt.y)/(laufPunkt.x-festPunkt.x)*(x1-festPunkt.x)+festPunkt.y;

x2=Transformation.wMaxX;
y2=(laufPunkt.y-festPunkt.y)/(laufPunkt.x-festPunkt.x)*(x2-festPunkt.x)+festPunkt.y;
g.setColor(farbe);
drawLineReal(g, x1, y1, x2, y2);
}

public void zeichneTangente(Graphics g, Color farbe){
/* Tangentengleichung t:
y = 2*(x-festpunkt.x)+ festpunkt.y
*/
double xBeginn, xEnde, yBeginn, yEnde;
g.setColor(farbe);
xBeginn = Transformation.wMinX;
xEnde = Transformation.wMaxX;
yBeginn = 2*festPunkt.x*(xBeginn-festPunkt.x)+ festPunkt.y;
yEnde = 2*festPunkt.x*(xEnde-festPunkt.x)+ festPunkt.y;
drawLineReal(g, xBeginn, yBeginn, xEnde, yEnde);
}

public void zeichneAchsenkreuz(Graphics g, Color farbe){
Point2DDouble A2D = new Point2DDouble(0,0);
Point2DDouble B2D = new Point2DDouble(0,0);

g.setColor(farbe);
// x-Achse zeichnen
A2D.x = Transformation.wMinX;
A2D.y = 0;
B2D.x = Transformation.wMaxX;;
B2D.y = 0;
drawLineReal(g, A2D.x, A2D.y, B2D.x, B2D.y);
// Pfeilspitze zeichnen
drawDreieckReal(g, Color.black, B2D.x, B2D.y, B2D.x-0.2, B2D.y+0.2, B2D.x-0.2, B2D.y-0.2);
beschrifteAchsenkreuz(g, farbe);

// y-Achse zeichnen
A2D.x = 0;
A2D.y = Transformation.wMinY;
B2D.x=0;
B2D.y=Transformation.wMaxY;
drawLineReal(g, A2D.x, A2D.y, B2D.x, B2D.y);
// Pfeilspitze zeichnen
drawDreieckReal(g, Color.black, B2D.x, B2D.y, B2D.x-0.2, B2D.y-0.2, B2D.x+0.2, B2D.y-0.2);
}

public void beschrifteAchsenkreuz(Graphics g, Color farbe){
double min, max, x, y;
//x-Achse beschriften
min = Transformation.wMinX;
max = Transformation.wMaxX;
x=0;
do{
//System.out.println(" min="+min+" max="+max+" x="+x);
drawLineReal(g, x, 0.1, x, -0.1);
x=x+1;
}
while (x<=max);

x=0;
do{
//System.out.println(" min="+min+" max="+max+" x="+x);
drawLineReal(g, x, 0.1, x, -0.1);
x=x-1;
}
while (x>=min);

//y-Achse beschriften
min = Transformation.wMinY;
max = Transformation.wMaxY;
y=0;
do{
//System.out.println(" min="+min+" max="+max+" x="+x);
drawLineReal(g, -0.1, y, 0.1, y);
y=y+1;
}
while (y<=max);

do{
//System.out.println(" min="+min+" max="+max+" x="+x);
drawLineReal(g, -0.1, y, 0.1, y);
y=y-1;
}
while (y>=min);


}


public void zeichneNormalparabel(Graphics g, Color farbe){
int sx, sy;
Graphics graphicsNormalparabel = null;
// Bereich der x-Werte D = [a, b]
double a, b;
int breiteInPixel;
int xScreenAlt, yScreenAlt, xScreen, yScreen;
double xwAlt, ywAlt, xw, yw;
int i;
a = Transformation.wMinX;
b = Transformation.wMaxX;
// Anzahl der Pixel berechnen zwischen A(-4,5|0) und B(4,5|0)
breiteInPixel = Transformation.transform2DWeltToScreenX(b)-
Transformation.transform2DWeltToScreenX(a);
//System.out.println("Anzahl der Pixel="+breiteInPixel);
//System.out.println("Transformation.getScreenBreite()="+Transformation.getScreenBreite()+"Transformation.getScreenHoehe()="+Transformation.getScreenHoehe());

g.setColor(farbe);
sx = zeichnungJPanel.getSize().width;
sy = zeichnungJPanel.getSize().height;
//System.out.println("sx="+sx+"=sy="+sy);

if(flag==0){
while (sx==0 && sy==0){
}
flag=1;
bildNormalparabel = zeichnungJPanel.createImage(sx, sy);
// Erzeuge den zu dem Grafikobjekt bild zugehörigen Grafikkontext,
// d.h. eine Leinwand, in die gemalt wird.
graphicsNormalparabel = bildNormalparabel.getGraphics();
// mit den 2 Anweisungen wird der Hintergrund ausgegeben
// unbedingt nötig
//graphics.setColor(getBackground());
graphicsNormalparabel.setColor(zeichnungJPanel.getBackground());
graphicsNormalparabel.fillRect(0,0,sx,sy);

graphicsNormalparabel.setColor(farbe);

//System.out.println("schrittbreite"+schrittbreite);
xScreenAlt = Transformation.transform2DWeltToScreenX(a);
yScreenAlt = Transformation.transform2DWeltToScreenY(a*a);
xScreen = xScreenAlt;
yScreen = yScreenAlt;
for(i=1;i<breiteInPixel;i++){
xScreen = xScreen + 1;
xw = Transformation.transformScreenTo2DWeltX(xScreen);
yw = xw*xw;
//System.out.println("xw="+xw+" yw="+yw);
yScreen = Transformation.transform2DWeltToScreenY(yw);
//System.out.println("xScreen+i="+(xScreen+i)+" yScreen="+yScreen);
//graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreen, yScreen);
graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreenAlt, yScreenAlt);
xScreenAlt = xScreen;
yScreenAlt = yScreen;
}
}
g.drawImage(bildNormalparabel,0,0,null);
}


public void drawLineReal(Graphics g, double x1, double y1, double x2, double y2){
Point A2DScreen, B2DScreen;
A2DScreen = Transformation.transform2DWeltToScreen(x1, y1);
B2DScreen = Transformation.transform2DWeltToScreen(x2, y2);
g.drawLine(A2DScreen.x, A2DScreen.y, B2DScreen.x, B2DScreen.y);
}


public void drawDreieckReal(Graphics g, Color farbe, double x1, double y1, double x2, double y2, double x3, double y3){
Point A2DScreen, B2DScreen, C2DScreen;
g.setColor(farbe);
A2DScreen = Transformation.transform2DWeltToScreen(x1, y1);
B2DScreen = Transformation.transform2DWeltToScreen(x2, y2);
C2DScreen = Transformation.transform2DWeltToScreen(x3, y3);

// Pfeil zeichnen
int[] xPoints = new int[3];
int[] yPoints = new int[3];
xPoints[0]=A2DScreen.x;
xPoints[1]=B2DScreen.x;;
xPoints[2]=C2DScreen.x;
yPoints[0]=A2DScreen.y;
yPoints[1]=B2DScreen.y;
yPoints[2]=C2DScreen.y;


g.fillPolygon(xPoints, yPoints, 3);
}

public void drawPunktReal(Graphics g, Color farbe, double x, double y){
int javaAbstand;
double xobenlinks, yobenlinks, xuntenrechts, yuntenrechts;
Point A2DScreen, B2DScreen;
g.setColor(farbe);

xobenlinks = x - abstand;
yobenlinks = y + abstand;
xuntenrechts = x + abstand;
yuntenrechts = y - abstand;

A2DScreen = Transformation.transform2DWeltToScreen(xobenlinks, yobenlinks);
B2DScreen = Transformation.transform2DWeltToScreen(xuntenrechts, yuntenrechts);
javaAbstand = B2DScreen.x -A2DScreen.x;

g.fillOval(A2DScreen.x, A2DScreen.y,javaAbstand, javaAbstand );
}




public boolean istInnerhalb(Point pJavaklick, Point2DDouble p2D){
boolean b;
double x,y;
int javaAbstand;
double xobenlinks, yobenlinks, xuntenrechts, yuntenrechts;
int xobenlinksScreen, yobenlinksScreen, xuntenrechtsScreen, yuntenrechtsScreen;
Point A2DScreen, B2DScreen;
x = p2D.x;
y = p2D.y;

xobenlinks = x - abstand;
yobenlinks = y + abstand;
xuntenrechts = x + abstand;
yuntenrechts = y - abstand;

A2DScreen = Transformation.transform2DWeltToScreen(xobenlinks, yobenlinks);
B2DScreen = Transformation.transform2DWeltToScreen(xuntenrechts, yuntenrechts);
xobenlinksScreen = A2DScreen.x;
yobenlinksScreen = A2DScreen.y;
xuntenrechtsScreen = B2DScreen.x;
yuntenrechtsScreen = B2DScreen.y;

b=pJavaklick.x>xobenlinksScreen && pJavaklick.x<xuntenrechtsScreen && pJavaklick.y>yobenlinksScreen && pJavaklick.y<yuntenrechtsScreen;
/*
System.out.println("pJavaklick.x="+pJavaklick.x+"xobenlinksJava"+xobenlinksJava);
System.out.println("pJavaklick.x="+pJavaklick.x+"xobenlinksJava"+xobenlinksJava);
*/
return b;

}


public boolean punktAufKurve(Point pJavaklick){
boolean b;
int genauigkeit;
Point2DDouble p2D;
double x2DExakt, y2DExakt;

genauigkeit = 3;
p2D = Transformation.transformScreenTo2DWelt(pJavaklick.x, pJavaklick.y);
x2DExakt = p2D.x;
y2DExakt = p2D.x*p2D.x;
System.out.println("x2DExakt="+x2DExakt+"y2DExakt="+y2DExakt);
b = p2D.y > y2DExakt - genauigkeit && p2D.y < y2DExakt + genauigkeit;
return b;
/*
System.out.println("pJavaklick.x="+pJavaklick.x+"xobenlinksJava"+xobenlinksJava);
System.out.println("pJavaklick.x="+pJavaklick.x+"xobenlinksJava"+xobenlinksJava);
*/
}


}

[/Java]
 

ernst

Top Contributor

Wenn man eine Mischung hat, d.h. ein Teil, der aufwändig zu zeichnen ist, und der in einem Offscreen-Bild liegen soll, und einen anderen Teil, der einfach zu zeichnen ist, und NICHT in einem Offscreen-Bild liegen soll, kann es etwas kniffliger werden, das vernünftig zu "verwalten"... In diesem Fall wäre das aber IMHO eigentlich auch nicht nötig...:

Hier ist der 2. Rest:

[Java]
package pack1;

import java.awt.Point;

public class Transformation {
// Höhe des Sreen
private static int sHoehe;
// Breite des Screen
private static int sBreite;
// Maximale x-Koordinate im Welt-Koordinatensystem
public static double wMaxX;
// Maximale y-Koordinate im Welt-Koordinatensystem
public static double wMaxY;
// Minimale x-Koordinate im Welt-Koordinatensystem
public static double wMinX;
// Minimale y-Koordinate im Welt-Koordinatensystem
public static double wMinY;


// statischer Konstruktor
static {


}

public static void setScreenBreite(int psb){
sBreite = psb;
}

public static void setScreenHoehe(int psh){
sHoehe = psh;
}

public static int getScreenBreite(){
return sBreite;
}


public static int getScreenHoehe(){
return sHoehe;
}

public static void setWeltMinMax(double pwMinX, double pwMinY, double pwMaxX, double pwMaxY){
wMinX=pwMinX;
wMinY=pwMinY;
wMaxX=pwMaxX;
wMaxY=pwMaxY;
}

public static Point transform2DWeltToScreen(double pxw, double pyw){
int xs, ys;
xs = (int)(sBreite/(wMaxX-wMinX) * (pxw-wMinX));
ys = (int) (sHoehe - sHoehe/(wMaxY-wMinY) * (pyw-wMinY));
return(new Point(xs, ys));
}


public static int transform2DWeltToScreenX(double pxw){
int xs;
xs = (int)(sBreite/(wMaxX-wMinX) * (pxw-wMinX));
return(xs);
}

public static int transform2DWeltToScreenY(double pyw){
int ys;
ys = (int) (sHoehe - sHoehe/(wMaxY-wMinY) * (pyw-wMinY));
return(ys);
}


public static Point2DDouble transformScreenTo2DWelt(int pxs, int pys){
double xw, yw;
xw = (wMaxX-wMinX)/sBreite *pxs + wMinX;
yw = (wMaxY-wMinY)/sHoehe * (sHoehe-pys) + wMinY;
return(new Point2DDouble(xw, yw));
}

public static double transformScreenTo2DWeltX(int pxs){
double xw;
xw = (wMaxX-wMinX)/sBreite *pxs + wMinX;
return(xw);
}

public static double transformScreenTo2DWeltY(int pys){
double yw;
yw = (wMaxY-wMinY)/sHoehe * (sHoehe-pys) + wMinY;
return(yw);
}


}







[/Java]

[Java]
package pack1;

import java.awt.Color;
import java.util.Hashtable;
import javax.swing.JLabel;
import javax.swing.JSlider;

public class ZeichnungJFrame extends javax.swing.JFrame {
private ZeichnungJPanel zeichnungJPanel;

public ZeichnungJFrame() {
String s1, s2, s3;
initComponents();
//getContentPane().setBackground(new java.awt.Color(255, 204, 153));
getContentPane().setBackground(Color.green);
s1="Sekantensteigung und Tangentensteigung: ";
s2="deltaX, x-Wert des Festpunktes (mit Schieberegler) und Laufpunkt ";
s3="(mit der Maus) veränderbar";
setTitle(s1+s2+s3);
int slidermin = -100;
int slidermax = 100;
this.setSize(1000, 700);

zeichnungJPanel = new ZeichnungJPanel(this);
// An die Zeichenfläche muss das SpielJFrame montiert werden.
jPanel1.add(zeichnungJPanel, "Center");
// Maximaler Wert, den der Slider (Schieberegöler ganz links) zurückgibt
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Kaum zu glauben, aber laut Debugger ruft setMinimum() die
// Methode jSlider1.changeEvent() auf
jSlider1.setMinimum(slidermin);
jSlider1.setMaximum(slidermax);
jSlider1.setOrientation(JSlider.HORIZONTAL);
jSlider1.setPaintLabels(true);
jSlider1.setPaintTicks(true);
jSlider1.setMajorTickSpacing(10 );
Hashtable labelTable = new Hashtable();
labelTable.put(new Integer(slidermin), new JLabel(Integer.toString(slidermin/10)));
labelTable.put(new Integer(0), new JLabel("0"));
labelTable.put(new Integer(slidermax), new JLabel(Integer.toString(slidermax/10)));
jSlider1.setLabelTable(labelTable);

// Maximaler Wert, den der Slider (Schieberegöler ganz links) zurückgibt
jSlider2.setMinimum(slidermin);
jSlider2.setMaximum(slidermax);
jSlider2.setOrientation(JSlider.HORIZONTAL);
jSlider2.setPaintLabels(true);
jSlider2.setPaintTicks(true);
jSlider2.setMajorTickSpacing(10 );
Hashtable labelTable2 = new Hashtable();
labelTable2.put(new Integer(slidermin), new JLabel(Integer.toString(slidermin/10)));
labelTable2.put(new Integer(0), new JLabel("0"));
labelTable2.put(new Integer(slidermax), new JLabel(Integer.toString(slidermax/10)));
jSlider2.setLabelTable(labelTable2);

jSlider1.setOpaque(false);
jSlider2.setOpaque(false);

}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jPanel1 = new javax.swing.JPanel();
jSlider1 = new javax.swing.JSlider();
jSlider2 = new javax.swing.JSlider();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
tx1 = new javax.swing.JTextField();
tx2 = new javax.swing.JTextField();
jLabel5 = new javax.swing.JLabel();
jLabel6 = new javax.swing.JLabel();
jLabel7 = new javax.swing.JLabel();
jLabel8 = new javax.swing.JLabel();
tx3 = new javax.swing.JTextField();
tx4 = new javax.swing.JTextField();
tx5 = new javax.swing.JTextField();
jLabel9 = new javax.swing.JLabel();
jLabel10 = new javax.swing.JLabel();
jLabel11 = new javax.swing.JLabel();
tx6 = new javax.swing.JTextField();
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jPanel1.setBackground(new java.awt.Color(204, 255, 204));
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setLayout(new java.awt.BorderLayout());

jSlider1.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
jSlider1StateChanged(evt);
}
});

jSlider2.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
jSlider2StateChanged(evt);
}
});

jLabel1.setText("delta x verändern");

jLabel2.setText("x-Wert des Festpunktes verändern");

jLabel3.setText("x-Koordinate Festpunkt");

jLabel4.setText("y-Koordinate Festpunkt");

tx1.setText("jTextField1");
tx1.setEnabled(false);

tx2.setText("jTextField2");
tx2.setEnabled(false);

jLabel5.setForeground(new java.awt.Color(255, 51, 51));
jLabel5.setText("deltaY");

jLabel6.setText("--------");

jLabel7.setForeground(new java.awt.Color(0, 51, 255));
jLabel7.setText("deltaX");

jLabel8.setText("=");

tx3.setForeground(new java.awt.Color(255, 51, 51));
tx3.setText("jTextField3");
tx3.setEnabled(false);

tx4.setForeground(new java.awt.Color(51, 51, 255));
tx4.setText("jTextField4");
tx4.setEnabled(false);

tx5.setText("jTextField5");
tx5.setEnabled(false);

jLabel9.setText("=");

jLabel10.setText("---------------------------------");

jLabel11.setText("-");

tx6.setText("jTextField6");
tx6.setEnabled(false);

jTextArea1.setColumns(20);
jTextArea1.setEditable(false);
jTextArea1.setRows(5);
jTextArea1.setText("I) Beschreibung (Einführung in die Differentialrechnung):\nDurch den Laufpunkt und den Festpunkt ist die Sekante festgelegt.\nDer Laufpunkt kann durch die Maus oder den oberen Schiebregler verändert \nwerden.\nDer Festpunkt kann nur durch den unteren Schieberegler verändert werden.\nDurch den Laufpunkt und den Festpunkt ist die Sekantensteigung bestimmt.\nSekantensteigung = deltaY : deltaX\n\nII) Aufgaben:\n1) Berechnen Sie die Sekantensteigung für deltax=1, 2, 3, 4\n\n2) Bewegen Sie dann den Laufpunkt immer weiter gegen den Festpunkt\nund überprüfen Sie Ihre Ergebnisse mit denen des Programms.\nGegen welche Steigung strebt dann die Sekantensteigung ?\n\n3) Welche Steigung hat damit die Tangente ? ");
jScrollPane1.setViewportView(jTextArea1);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 543, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, 399, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, 390, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel3)
.addGap(18, 18, 18)
.addComponent(tx1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(229, 229, 229))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5)
.addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel7))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel8)
.addGap(12, 12, 12)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(14, 14, 14)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(jLabel9)
.addGap(18, 18, 18)
.addComponent(tx6, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(tx3, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(26, 26, 26)
.addComponent(tx4, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addGroup(layout.createSequentialGroup()
.addGap(60, 60, 60)
.addComponent(tx5, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel4)
.addGap(18, 18, 18)
.addComponent(tx2, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(229, 229, 229)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(814, 814, 814))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 1250, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSlider2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel11)
.addGap(92, 92, 92))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel3)
.addComponent(tx1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel4)
.addComponent(tx2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tx3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel5)
.addComponent(tx4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel10)
.addComponent(jLabel9)
.addComponent(jLabel6)
.addComponent(jLabel8)
.addComponent(tx6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel7))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(tx5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(2, 2, 2)))
.addContainerGap())))
);

pack();
}// </editor-fold>

private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {
String str;
int wert;
// double Wert
double dWert;
wert = jSlider1.getValue();
// mache daraus einen doubel-Wert:
dWert = wert / 10.0;
zeichnungJPanel.setParameterDeltaX(dWert);
zeichnungJPanel.allesUpdaten();
zeichnungJPanel.maleKomplettesFenster();
//System.out.println("jSlider1StateChanged wurde aufgerufen");
}

private void jSlider2StateChanged(javax.swing.event.ChangeEvent evt) {
String str;
int wert;
// double Wert
double dWert;
wert = jSlider2.getValue();
// mache daraus einen doubel-Wert:
dWert = wert / 10.0;

zeichnungJPanel.setParameterXFestpunkt(dWert);
zeichnungJPanel.allesUpdaten();
zeichnungJPanel.maleKomplettesFenster();
//System.out.println("jSlider2StateChanged wurde aufgerufen");
}


public void maleRestZeichnungJFrame(){
String str;
float ergebnis;
double xFestpunkt, yFestpunkt, xLaufpunkt, yLaufpunkt, erg;
xFestpunkt = zeichnungJPanel.getTangente().getFestPunkt().x;
yFestpunkt = zeichnungJPanel.getTangente().getFestPunkt().y;
xLaufpunkt = zeichnungJPanel.getTangente().getLaufPunkt().x;
yLaufpunkt = zeichnungJPanel.getTangente().getLaufPunkt().y;

//System.out.println("_xFestpunkt="+xFestpunkt);
//System.out.println("_xLaufpunkt=="+xLaufpunkt);

int sliderwert;
//System.out.println("xLaufpunkt-xFestpunkt=="+(xLaufpunkt-xFestpunkt)+" sliderwert="+sliderwert);
/* A C H T U N G:
sliderwert=(int)((xLaufpunkt-xFestpunkt)*10);
lieferte
xLaufpunkt-xFestpunkt==2.9999999999999996 und damit
sliderwert=29
D E S W E G EN die folgende Konstruktion
*/
ergebnis=(float)((xLaufpunkt-xFestpunkt)*10);
sliderwert=Math.round(ergebnis);
jSlider1.setValue(sliderwert);

sliderwert=(int)(xFestpunkt*10);
jSlider2.setValue(sliderwert);

str = new String(String.valueOf(xFestpunkt));
tx1.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(yFestpunkt));
tx2.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(yLaufpunkt));
tx3.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(yFestpunkt));
tx4.setText(str.substring(0,str.length()<6?str.length():5));

str = new String(String.valueOf(xLaufpunkt-xFestpunkt));
tx5.setText(str.substring(0,str.length()<6?str.length():5));

String s;
if (xLaufpunkt-xFestpunkt==0)
s="nicht definiert";
else{
erg = (yLaufpunkt-yFestpunkt)/(xLaufpunkt-xFestpunkt);
str = new String(String.valueOf(erg));
s = str.substring(0,str.length()<6?str.length():5);
}
tx6.setText(s);
}


public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// Orginal
//new ZeichnungJFrame().setVisible(true);
ZeichnungJFrame zeichnungJFrame = new ZeichnungJFrame();
zeichnungJFrame.setVisible(true);
zeichnungJFrame.zeichnungJPanel.setParameterDeltaX(3);
zeichnungJFrame.zeichnungJPanel.setParameterXFestpunkt(1);
zeichnungJFrame.zeichnungJPanel.allesUpdaten();
zeichnungJFrame.zeichnungJPanel.maleKomplettesFenster();

}
});
}

// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;
private javax.swing.JLabel jLabel11;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JSlider jSlider1;
private javax.swing.JSlider jSlider2;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JTextField tx1;
private javax.swing.JTextField tx2;
private javax.swing.JTextField tx3;
private javax.swing.JTextField tx4;
private javax.swing.JTextField tx5;
private javax.swing.JTextField tx6;
// End of variables declaration

}

[/Java]
 

ernst

Top Contributor
Das ist ja oben schon angedeutet ;) Ich glaube, einer der wichtigsten Punkte ist, die Funktion nur an den (Welt)koordinaten auszuwerten, die den Pixelpositionen entsprechen. Damit geht das ganze schon sehr flott. (Eigentlich auch für komplizierte Funktionen - dass man in der paint-Methode nicht so viel rechnen sollte, könnte man da schon fast als eine "Prinzipsache" bezeichnen...)

Hier der 3. Rest

[Java]
package pack1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
//import java.awt.image.BufferedImage;


public class ZeichnungJPanel extends javax.swing.JPanel implements MouseListener, MouseMotionListener {
ZeichnungJFrame zeichnungJFrame;
// private BufferedImage bild;
private Image bild;
private Tangente tangente;
// Parameter t der Geraden
private double parameterDeltaX;
private double parameterxFestpunkt;
private Graphics graphicsNormalparabel;
// private BufferedImage bildNormalparabel;
private Image bildNormalparabel;
private int anzahlMausImPunkt;
private int flag = 0;



public ZeichnungJPanel(ZeichnungJFrame pZeichnungJFrame) {
initComponents();
zeichnungJFrame = pZeichnungJFrame;
// Welt-Koordinatensystem festlegen
Transformation.setWeltMinMax(-4.5, -1, 4.5, 16);
tangente = new Tangente(this);
addMouseMotionListener(this);
addMouseListener(this);
parameterDeltaX=3;
parameterxFestpunkt=1;
anzahlMausImPunkt=0;

}

/**
* Gibt Tangente zurück.<br><br>
* <b>Beispiel:</b><br>
* tangente.getTangente();<br>
* @param pp1 (i) erster Punkt
* @param pp2 (i) zweiter Punkt
* @throws Throwable wenn die zwei Punkte identisch sind
*/
public Tangente getTangente(){
return tangente;
}

/**
* legt Festpunkt auf Parabel fest.<br><br>
* @param pp1 (i) Festpunkt
*/

public void setParameterXFestpunkt(double pParameterxFestpunkt){
parameterxFestpunkt = pParameterxFestpunkt;
}

public double getParameterXFestpunkt(){
return parameterxFestpunkt;
}

public void setParameterDeltaX(double pDeltaX){
parameterDeltaX = pDeltaX;
}

public double getParameterDeltaX(){
return parameterDeltaX;
}

public void allesUpdaten() {
//System.out.println("this.getWidth()="+this.getWidth()+"this.getHeight="+this.getHeight());
tangente.berechnePos();
}

public void maleKomplettesFenster(){
maleZeichnungJPanelOffscreen();
zeichnungJFrame.maleRestZeichnungJFrame();
repaint();
}


public void maleZeichnungJPanelOffscreen(){
int sx, sy;
Graphics graphics=null;

sx = this.getSize().width;
sy = this.getSize().height;

/*
Ein Bild zu erstellen ist aufwändig: es muss Speicher allokiert
und gecleart werden. Deshalb sollte das nur einmal gemacht werden.
*/
/* Da sx und sy erts nach der Anweisung
zeichnungJFrame.setVisible(true);
einen Wert != 0 haben, aber die folgenden Anweisungen schon vorher
durchgeführt werden, muss sx und sy abgefragt werden
*/
if(bild==null || bild.getWidth(this)!=sx || bild.getHeight(this)!=sy){
if(sx!=0 && sy!=0){
bild = createImage(sx, sy);
Transformation.setScreenBreite(sx);
Transformation.setScreenHoehe(sy);
flag=1;
}
}
if(flag==1){
graphics = bild.getGraphics();
// mit den 2 Anweisungen wird der Hintergrund ausgegeben
// unbedingt nötig
graphics.setColor(getBackground());
graphics.fillRect(0,0,sx,sy);

tangente.zeichneNormalparabel(graphics, Color.black);
tangente.zeichneSekante(graphics, Color.green);
//tangente.zeichneTangente(graphics, Color.cyan);
tangente.zeichneTangente(graphics, Color.orange);
tangente.zeichneAchsenkreuz(graphics, Color.black);
/*
Wenn dies jetzt erst gemacht wird, wird Sekante, usw
nicht mehr angezeigt. Warum ?
*/
// tangente.zeichneNormalparabel(graphics, Color.black);
}
}


public void paintComponent(Graphics g) {
super.paintComponent(g);
//g.setColor(this.getBackground());
//setBackground(Color.white);
// Warum wird kein weißer Hintergrund gezeichnet ????
//g.drawImage(bild,0,0,Color.white,null);
g.drawImage(bild,0,0,null);

}

public void mouseClicked(MouseEvent arg0) {
}

public void mousePressed(MouseEvent arg0) {
}

public void mouseEntered(MouseEvent arg0) {
}

public void mouseExited(MouseEvent arg0) {
}

public void mouseMoved(MouseEvent arg0) {
}

public void mouseDragged(MouseEvent ev) {
boolean b=true;
Point2DDouble p2D;
Point javaklick = new Point();
javaklick = ev.getPoint();
// Der Mauszeiger befindet sich innerhalb des Laufpunkts
if(anzahlMausImPunkt==0){
b = tangente.istInnerhalb(javaklick, tangente.getLaufPunkt());
if(b==true)
anzahlMausImPunkt=1;
}

if(anzahlMausImPunkt==1){
// Zeichne den Punkt an die Mauskoordinaten
p2D = Transformation.transformScreenTo2DWelt(javaklick.x, javaklick.y);
setParameterDeltaX(p2D.x-tangente.getFestPunkt().x);
allesUpdaten();
maleKomplettesFenster();
}
}


public void mouseReleased(MouseEvent ev) {
boolean b;
Point javaklick = new Point();
Point2DDouble p2D;

javaklick = ev.getPoint();
//System.out.println("javaklick.x="+javaklick.x+"javaklick.y"+javaklick.y);
if(anzahlMausImPunkt==1){
anzahlMausImPunkt=0;
}
//System.out.println("mouseReleased wurde aufgerufen");
}


/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

setBackground(new java.awt.Color(255, 255, 255));

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 523, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 312, Short.MAX_VALUE)
);
}// </editor-fold>


// Variables declaration - do not modify
// End of variables declaration

}

[/Java]
 

Marco13

Top Contributor
1) Wenn ich BufferedImage benutzte (statt Image) sagt mir der Compiler, dass er createImage nicht kennt. Was kann ich machen, damit er das kennt?


Bei BufferedImage macht man statt createImage(w,h) sowas wie
Code:
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);


2) Kann ich statt BufferedImage auch Image benutzen (so wie in meinem Programm), oder welche Nachteile hole ich mir mit Image statt BuffereImage ?


Neenaja... Image hat nicht direkt "Nachteile" - genaugenommen galt bis vor einiger Zeit auch die Empfehlung, "createImage" zu verwenden, weil damit schnellere Bilder erzeugt wurden, aber das ist obsolet. Ein ""Vorteil"" von BufferedImage ist, dass man bei getWidth/getHeight keinen ImageObserver übergeben muss, und ein paar mehr Möglichkeiten hat... die du aber wohl hier nicht brauchst...


3)
Wenn ich die Parabel nur einmal zeichne, unten öfters mal das Fenster verkleiner und vergrößere und dabei den unteren Schieberegler verstelle, wird meine Parabel manchmal etwas verschoben.
An was liegt das?
Wie kann ich es ändern (ohne dass ich die Parabel jedesmal neu zeichne) ?

Naja... wenn man das Fenster größer zieht, dann MUSS die Parabel neu gezeichnet werden, weil der Teil, der durch die Vergrößerung dazu kommt, ja noch nicht (im Bild) existiert. Abgesehen davon hatte ich ja gesagt, dass das Bild (zwar nicht bei jedem Zeichnen, aber doch) bei jeder Größenänderung neu erstellt werden muss - wenn man denn nicht versucht, komplett auf das Image zu verzichten...


Ist deiner Meinung nach der Hintergrund wirklich weiss?


Meinungen sind Murks. Hab' einen Screenshot gemacht, und er zeigt mir für den Hintergrund als Farbe 255,255,255 an - das ist so weiß, wie es eben geht ;)

BTW: Wenn du die Zeile
graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreenAlt, yScreenAlt);
änderst in
graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreen, yScreen);
ist die Parabel auch wieder eine schön durchgezogene Linie...
 

ernst

Top Contributor
3)
Wenn ich die Parabel nur einmal zeichne, unten öfters mal das Fenster verkleiner und vergrößere und dabei den unteren Schieberegler verstelle, wird meine Parabel manchmal etwas verschoben.
An was liegt das?
Wie kann ich es ändern (ohne dass ich die Parabel jedesmal neu zeichne) ?
[/i]
Naja... wenn man das Fenster größer zieht, dann MUSS die Parabel neu gezeichnet werden, weil der Teil, der durch die Vergrößerung dazu kommt, ja noch nicht (im Bild) existiert. Abgesehen davon hatte ich ja gesagt, dass das Bild (zwar nicht bei jedem Zeichnen, aber doch) bei jeder Größenänderung neu erstellt werden muss - wenn man denn nicht versucht, komplett auf das Image zu verzichten...
Ok, ich frage also immer vorher ab, ob das Fensters vergrößert oder verkleinert wurde.
Dies mache ich mit
System.out.println("bild.getWidth(this)="+bild.getWidth(this)+" sx="+sx);
System.out.println("bild.getHeight(this)="+bild.getHeight(this)+" sy="+sy);
Allerdings sind die Werte immer gleich (Ausdruck auf Bildschirm):
run:
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=664 sy=664
Hallo wie oft bin ich hier?
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=664 sy=664
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=682 sy=682
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=703 sy=703

Wo ist mein Denkfehler ?

mfg
Ernst

Hier ein Programausschnitt:

[Java]
public void maleZeichnungJPanelOffscreen(){
...
System.out.println("bild.getWidth(this)="+bild.getWidth(this)+" sx="+sx);
System.out.println("bild.getHeight(this)="+bild.getHeight(this)+" sy="+sy);

if(bild.getWidth(this)!=sx || bild.getHeight(this)!=sy)
// Neuzeichnen der Parabel
tangente.zeichneNormalparabel(graphics, Color.black, 1);
else
// Parabel muss nicht neu gezeichnet werden
tangente.zeichneNormalparabel(graphics, Color.black, 0);
...
}

[/Java]
 

Marco13

Top Contributor
Hm. Der y-Wert ändert sich doch?!

Aber ... ich habe jetzt das letzte, was du gepostet hattest, nochmal angesehen: Dass die Parabel nicht (oder verschoben) gezeichnet wurde, hängt wohl irgendwie mit dem "flag" zusammen... Ich hatte das mal so geändert....
Java:
    public void zeichneNormalparabel(Graphics g, Color farbe)
    {
        int sx, sy;
        Graphics graphicsNormalparabel = null;
        // Bereich der x-Werte D = [a, b]
        double a, b;
        int breiteInPixel;
        int xScreenAlt, yScreenAlt, xScreen, yScreen;
        double xwAlt, ywAlt, xw, yw;
        int i;
        a = Transformation.wMinX;
        b = Transformation.wMaxX;
        // Anzahl der Pixel berechnen zwischen A(-4,5|0) und B(4,5|0)
        breiteInPixel = Transformation.transform2DWeltToScreenX(b) - Transformation.transform2DWeltToScreenX(a);
        // System.out.println("Anzahl der Pixel="+breiteInPixel);
        // System.out.println("Transformation.getScreenBreite()="+Transformation.getScreenBreite()+"Transformation.getScreenHoehe()="+Transformation.getScreenHoehe());

        g.setColor(farbe);
        sx = zeichnungJPanel.getSize().width;
        sy = zeichnungJPanel.getSize().height;
        // System.out.println("sx="+sx+"=sy="+sy);

        // if(flag==0)
        {
            while (sx == 0 && sy == 0)
            {}
            flag = 1;

            if (bildNormalparabel == null || bildNormalparabel.getWidth(zeichnungJPanel) != sx || bildNormalparabel.getHeight(zeichnungJPanel) != sy)
            {
                System.out.println("Zeichne Parabel neu!");
                bildNormalparabel = zeichnungJPanel.createImage(sx, sy);

                // Erzeuge den zu dem Grafikobjekt bild zugehörigen
                // Grafikkontext,
                // d.h. eine Leinwand, in die gemalt wird.
                graphicsNormalparabel = bildNormalparabel.getGraphics();
                // mit den 2 Anweisungen wird der Hintergrund ausgegeben
                // unbedingt nötig
                // graphics.setColor(getBackground());
                graphicsNormalparabel.setColor(zeichnungJPanel.getBackground());
                graphicsNormalparabel.fillRect(0, 0, sx, sy);

                graphicsNormalparabel.setColor(farbe);

                // System.out.println("schrittbreite"+schrittbreite);
                xScreenAlt = Transformation.transform2DWeltToScreenX(a);
                yScreenAlt = Transformation.transform2DWeltToScreenY(a * a);
                xScreen = xScreenAlt;
                yScreen = yScreenAlt;
                for (i = 1; i < breiteInPixel; i++)
                {
                    xScreen = xScreen + 1;
                    xw = Transformation.transformScreenTo2DWeltX(xScreen);
                    yw = xw * xw;
                    // System.out.println("xw="+xw+" yw="+yw);
                    yScreen = Transformation.transform2DWeltToScreenY(yw);
                    // System.out.println("xScreen+i="+(xScreen+i)+"
                    // yScreen="+yScreen);
                    // graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt,
                    // xScreen, yScreen);
                    graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreen, yScreen);
                    xScreenAlt = xScreen;
                    yScreenAlt = yScreen;
                }
            }
            else
            {
                System.out.println("Verwende alte Parabel");
            }
        }
        g.drawImage(bildNormalparabel, 0, 0, null);
    }

Und jetzt sagt er NUR bei Größenänderungen (EIN mal) dass er die Parabel neu zeichnet, und ansonsten die alte verwendet. Pass' auf dass du nicht versuchst, Fehler zu beheben, deren Ursache du nicht kennst - dadurch kann Code schnell chaotisch werden.

Das mit dem Zeichnen der Parabel hatte ich auch nochmal angesehen: Das
Java:
        a = Transformation.wMinX;
        b = Transformation.wMaxX;
        // Anzahl der Pixel berechnen zwischen A(-4,5|0) und B(4,5|0)
        breiteInPixel = Transformation.transform2DWeltToScreenX(b) - Transformation.transform2DWeltToScreenX(a);
ist ein bißchen von Hinten durch die Brust ins Auge ;) Schau dir mal an, was bei den beiden transform-Aufrufen und der Breite dann am Ende so rauskommt ;)
 

ernst

Top Contributor
Hm. Der y-Wert ändert sich doch?!

1)
Ich glaube, dass ich irgendwas mit dem getWidth bzw. getHeigh nicht verstanden habe (Bem: Ich benutze Image).
Ich habe in deinem Quellcode gefunden:
bildNormalparabel.getWidth(zeichnungJPanel) != sx
sx = zeichnungJPanel.getSize().width;
Das kann ich nachvollziehen:
Du vergleichst die Breite der Zeichenfläche (die der User durch Ziehen abändern kann) mit der Breite, des Bildes das von der Zeichenfläche gemacht wurde. Und diese Bildbreite hat konstant den Wert, den sie beim Anlegen abgekriegt hat.

Bei mir ist es:
bild.getWidth(this)!=sx
sx = this.getSize().width;

Eigentlich will ich prüfen:
bild.getWidth(bild)!=sx
sx = this.getSize().width;
Aber das läßt der Compiler nicht zu: Er will einen Observer (was immer das auch sei).
Ich will aber die (konstante) Bildbreite, die beim Erzeugen des Bildes fest angelegt wurde (unveränderbar).

Siehe 2)

2)
Du hast recht. Es ändert sich etwas, z.B. eine Ausgabe für den Quellcode unten:
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=664 sy=664
NICHT Neuzeichnen der Parabel
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=526 sy=526 <----
NICHT Neuzeichnen der Parabel
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=526 sy=526
NICHT Neuzeichnen der Parabel
bild.getWidth(this)=541 sx=541
bild.getHeight(this)=526 sy=526

Deshalb (weil sich etwas ändert) verstehe ich nicht, warum die Parabel nicht neu gezeichnet wird. Es kommt immer die Ausgabe:
"NICHT Neuzeichnen der Parabel"
Vermutlich weil
bild.getWidth(this) eben nicht bild.getWidth(bild) als Ergebnis liefert.

Wo ist mein Denkfehler?

[Java]
public void maleZeichnungJPanelOffscreen(){
int sx, sy;
Graphics graphics=null;

sx = this.getSize().width;
sy = this.getSize().height;

if(bild==null || bild.getWidth(this)!=sx || bild.getHeight(this)!=sy){
if(sx!=0 && sy!=0){
bild = createImage(sx, sy);
Transformation.setScreenBreite(sx);
Transformation.setScreenHoehe(sy);
flag=1;
}
}
if(flag==1){
graphics = bild.getGraphics();
graphics.setColor(getBackground());
graphics.fillRect(0,0,sx,sy);

System.out.println("bild.getWidth(this)="+bild.getWidth(this)+" sx="+sx);
System.out.println("bild.getHeight(this)="+bild.getHeight(this)+" sy="+sy);

if(bild.getWidth(this)!=sx || bild.getHeight(this)!=sy){
System.out.println("NEU-zeichnen der Parabel");
tangente.zeichneNormalparabel(graphics, Color.black, 1);
}
else{

System.out.println("NICHT Neuzeichnen der Parabel");
tangente.zeichneNormalparabel(graphics, Color.black, 0);
}
...
}
[/Java]


mfg
Ernst
 

Marco13

Top Contributor
Bei mir ist es:
bild.getWidth(this)!=sx
sx = this.getSize().width;

Eigentlich will ich prüfen:
bild.getWidth(bild)!=sx
sx = this.getSize().width;
Aber das läßt der Compiler nicht zu: Er will einen Observer (was immer das auch sei).


Da ist er wieder, der ImageObserver, den man beim BufferedImage nicht bräuchte :D
Man kann bei "getWidth" irgendeine Component übergeben.
bild.getWidth(zeichnungJPanel);
liefert (auch wenn das vielleicht verwirrend aussieht) die Breite des BILDES, und nicht die Breite des JPanels (theoretisch könnte man auch bild.getWidth(null); machen, aber das könnte manchmal nicht funktionieren).



Deshalb (weil sich etwas ändert) verstehe ich nicht, warum die Parabel nicht neu gezeichnet wird. Es kommt immer die Ausgabe:
"NICHT Neuzeichnen der Parabel"
Vermutlich weil
bild.getWidth(this) eben nicht bild.getWidth(bild) als Ergebnis liefert.


Ich glaube, es besteht allgemein ein bißchen Verwirrung wegen der beiden Offscreen-Bilder, und der Frage, wer die wann wo anlegt und wie man die Größe bestimmt, und insbesondere, wann was neu gezeichnet werden muss. Vielleicht habe ich auch deine Absicht falsch verstanden. Ich denke, du willst die Parabel nur EINmal in ein Bild zeichnen. (Und nur neu in ein neues Bild zeichnen, wenn sich die größe Ändert). Und ansonsten soll immer das fertige Parabelbild in das "Gesamtbild" gemalt werden?!


EDIT: Es kommt immer die "NICHT"-Ausgabe, weil ein paar Zeilen weiter oben schon sichergestellt wurde, dass das Bild dir größe sx/sy hat! Vollzieh' das nochmal in Ruhe nach, und schreib' dir vielleicht mal im Pseudocode mit klar benannten Variablen (und ggf. erstmal leeren "dummy-Funktionen") auf, was dort ablaufen muss....
 
Zuletzt bearbeitet:

ernst

Top Contributor
EDIT: Es kommt immer die "NICHT"-Ausgabe, weil ein paar Zeilen weiter oben schon sichergestellt wurde, dass das Bild dir größe sx/sy hat! Vollzieh' das nochmal in Ruhe nach, und schreib' dir vielleicht mal im Pseudocode mit klar benannten Variablen (und ggf. erstmal leeren "dummy-Funktionen") auf, was dort ablaufen muss....
1)
Danke für deine Geduld. Ich bin irgendwie ganz durcheinander gekommen und habe deshalb nochmals überlegt:
Den Flag brauche ich nicht: ich kann alles damit erledigen, daß ich die Bildgröße mit der Größe der Zeichenfläche vergleiche!
Jetzt klappt es!
Unten nochmals die 2 Methdeon.

2)
In dem Konstruktor
public ZeichnungJFrame() {
kommt die Anweisung
jSlider1.setMinimum(slidermin);
vor.
Es istkaum zu glauben, aber laut Debugger ruft setMinimum() die Methode jSlider1.changeEvent() auf.
In dieser wird aber die Methode
maleZeichnungJPanelOffscreen()
aufegrufen, die u.a.
sx = this.getSize().width;
macht. Da dies aber alles noch vor setVisible(true) passiert, ist dort sx gleich 0.
Deswegen muß ich immer noch abfragen:
if(sx!=0 && sy!=0)
...
Ist das okay, bzw. was meinst du dazu?

3) Noch eine Verständnisfrage (siehe unten public void maleZeichnungJPanelOffscreen())
Wenn ich die Normalparabel erst ganz am Schluss dieser Anweisungen mache, wird Sekante, Tangente, usw
nicht mehr angezeigt. Warum ?

//tangente.zeichneNormalparabel(graphics, Color.black);
tangente.zeichneSekante(graphics, Color.green);
tangente.zeichneTangente(graphics, Color.orange);
tangente.zeichneAchsenkreuz(graphics, Color.black);
tangente.zeichneNormalparabel(graphics, Color.black);

mfg
Ernst


[Java]
public void zeichneNormalparabel(Graphics g, Color farbe){
int sx, sy;
Graphics graphicsNormalparabel = null;
double wMinX;
int breiteInPixel;
int xScreenAlt, yScreenAlt, xScreen, yScreen;
double xwAlt, ywAlt, xw, yw;
int i;

breiteInPixel = Transformation.getScreenBreite();
g.setColor(farbe);
sx = zeichnungJPanel.getSize().width;
sy = zeichnungJPanel.getSize().height;

if(bildNormalparabel==null || bildNormalparabel.getWidth(null)!=sx || bildNormalparabel.getHeight(null)!=sy){
if(sx!=0 && sy!=0){
bildNormalparabel = zeichnungJPanel.createImage(sx, sy);
}
}

if(sx!=0 && sy!=0){
// Erzeuge den zu dem Grafikobjekt bild zugehörigen Grafikkontext,
// d.h. eine Leinwand, in die gemalt wird.
graphicsNormalparabel = bildNormalparabel.getGraphics();
// mit den 2 Anweisungen wird der Hintergrund ausgegeben
// unbedingt nötig
graphicsNormalparabel.setColor(zeichnungJPanel.getBackground());
graphicsNormalparabel.fillRect(0,0,sx,sy);
graphicsNormalparabel.setColor(farbe);
wMinX = Transformation.wMinX;
xScreenAlt = Transformation.transform2DWeltToScreenX(wMinX);
yScreenAlt = Transformation.transform2DWeltToScreenY(wMinX*wMinX);
xScreen = xScreenAlt;
yScreen = yScreenAlt;

for(i=1;i<breiteInPixel;i++){
xScreen = xScreen + 1;
xw = Transformation.transformScreenTo2DWeltX(xScreen);
yw = xw*xw;
yScreen = Transformation.transform2DWeltToScreenY(yw);
graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreen, yScreen);
// Kurve als einzelne Punkte darstellen
graphicsNormalparabel.drawLine(xScreenAlt, yScreenAlt, xScreenAlt, yScreenAlt);
xScreenAlt = xScreen;
yScreenAlt = yScreen;
}
}
g.drawImage(bildNormalparabel,0,0,null);
}

[/Java]
[Java]
public void maleZeichnungJPanelOffscreen(){
int sx, sy;
Graphics graphics=null;

sx = this.getSize().width;
sy = this.getSize().height;

if(bild==null || bild.getWidth(this)!=sx || bild.getHeight(this)!=sy){
if(sx!=0 && sy!=0){
bild = createImage(sx, sy);
Transformation.setScreenBreite(sx);
Transformation.setScreenHoehe(sy);
}
}


if(sx!=0 && sy!=0){
graphics = bild.getGraphics();
// mit den 2 Anweisungen wird der Hintergrund ausgegeben
// unbedingt nötig
graphics.setColor(getBackground());
graphics.fillRect(0,0,sx,sy);

tangente.zeichneNormalparabel(graphics, Color.black);
tangente.zeichneSekante(graphics, Color.green);
tangente.zeichneTangente(graphics, Color.orange);
tangente.zeichneAchsenkreuz(graphics, Color.black);
/*
Wenn dies jetzt erst gemacht wird, wird Sekante, usw
nicht mehr angezeigt. Warum ?
*/
// tangente.zeichneNormalparabel(graphics, Color.black);
}

}
[/Java]
 

Marco13

Top Contributor
Ein paar der Fragen hatte ich schon als Kommentare im Code gesehen ;)


In dem Konstruktor
public ZeichnungJFrame() {
kommt die Anweisung
jSlider1.setMinimum(slidermin);
vor.
Es istkaum zu glauben, aber laut Debugger ruft setMinimum() die Methode jSlider1.changeEvent() auf.


(Das ist auch gut so ... das muss so sein ;) )


In dieser wird aber die Methode
maleZeichnungJPanelOffscreen()
aufegrufen, die u.a.
sx = this.getSize().width;
macht. Da dies aber alles noch vor setVisible(true) passiert, ist dort sx gleich 0.
Deswegen muß ich immer noch abfragen:
if(sx!=0 && sy!=0)
...
Ist das okay, bzw. was meinst du dazu?


Joa, man könnte sich da jetzt eine Reihe möglicher Lösungen überlegen... aber im Endeffekt wird's immer auf so eine ähnliche Abfrage rauslaufen...

EDIT: Eine einfache (und spontan würde ich sagen: Die beste) Abhilfe könnte sein, den ChangeListener erst an den Slider zu hängen, NACHDEM man das anfängliche setMinimum aufgerufen hat...)



3) Noch eine Verständnisfrage (siehe unten public void maleZeichnungJPanelOffscreen())
Wenn ich die Normalparabel erst ganz am Schluss dieser Anweisungen mache, wird Sekante, Tangente, usw
nicht mehr angezeigt. Warum ?


Weil die Normalparabel (bei dir) nicht eine Linie ist, die in das Graphics gemalt wird, sondern ein Bild - ein Bild, das hauptsächlich aus weißen Hintergrund besteht, und das Graphics voll ausfüllt (und alles übermalt, was vorher gemalt wurde). Solche Dinge meinte ich, als ich weiter oben was gebrabbelt habe von
"Wenn man eine Mischung hat, d.h. ein Teil, der aufwändig zu zeichnen ist, und der in einem Offscreen-Bild liegen soll, und einen anderen Teil, der einfach zu zeichnen ist, und NICHT in einem Offscreen-Bild liegen soll, kann es etwas kniffliger werden, das vernünftig zu "verwalten"... In diesem Fall wäre das aber IMHO eigentlich auch nicht nötig...:"

(NOCH kniffliger würde es eben werden, wenn man mehrerer solcer Buffer hätte, und keinen malen könnte, ohne potentiell einen anderen zu überdecken - dann könnte man zwar mit teilweise transparenten Bildern was machen, aber dadurch würde es dann wieder deutlich langsamer usw...)
 

ernst

Top Contributor
Es istkaum zu glauben, aber laut Debugger ruft setMinimum() die Methode jSlider1.changeEvent() auf.
[/i]

(Das ist auch gut so ... das muss so sein ;) )
Warum?
Woher weiss man das?
(Ich bin bin erst mit Hilfe des Debuggers darauf gekommen)

EDIT: Eine einfache (und spontan würde ich sagen: Die beste) Abhilfe könnte sein, den ChangeListener erst an den Slider zu hängen, NACHDEM man das anfängliche setMinimum aufgerufen hat...)
Das hat bei mir der Visual-Editor gemacht.
Wenn ich den weiter benutze, kann ich diese Lösung nicht verwenden.

mfg
Ernst
 

Marco13

Top Contributor
Warum?
Woher weiss man das?
(Ich bin bin erst mit Hilfe des Debuggers darauf gekommen)

"Wissen" ist so eine Sache ... Man müßte es (wenn z.B. eine NullPointerException fliegt) am StackTrace sehen - und es steht auch in JSlider (Java Platform SE 6) ...


Das hat bei mir der Visual-Editor gemacht.
Wenn ich den weiter benutze, kann ich diese Lösung nicht verwenden.


Hmja, man stößt mit sowas eben manchmal en Grenzen. Die sind vielleicht praktisch, wenn man mal schnell ein "Mock-Up" oder irgendeinen Standard-Dialog zusammenklicken will, aber wenn's dann an solche Sachen geht, muss man aufpassen, dass die Einfachheit um Zeitersparnis, die man sich durch solche Editoren erhofft oder verspricht, nicht ins Gegenteil umschlägt...
 

ernst

Top Contributor
"Wissen" ist so eine Sache ... Man müßte es (wenn z.B. eine NullPointerException fliegt) am StackTrace sehen - und es steht auch in JSlider (Java Platform SE 6) ...
Du meinst damit:
If the new minimum value is different from the previous minimum value, all change listeners are notified.
D.h. die Listener werden aufgerufen

Hmja, man stößt mit sowas eben manchmal en Grenzen. Die sind vielleicht praktisch, wenn man mal schnell ein "Mock-Up" oder irgendeinen Standard-Dialog zusammenklicken will, aber wenn's dann an solche Sachen geht, muss man aufpassen, dass die Einfachheit um Zeitersparnis, die man sich durch solche Editoren erhofft oder verspricht, nicht ins Gegenteil umschlägt...

Wenn man mit dem VE mal Probleme bekommt und sich nicht genau auskennt, dann hat man ein Problem...

mfg
Ernst
 

ernst

Top Contributor
"Wissen"
Hmja, man stößt mit sowas eben manchmal en Grenzen. Die sind vielleicht praktisch, wenn man mal schnell ein "Mock-Up" oder irgendeinen Standard-Dialog zusammenklicken will, aber wenn's dann an solche Sachen geht, muss man aufpassen, dass die Einfachheit um Zeitersparnis, die man sich durch solche Editoren erhofft oder verspricht, nicht ins Gegenteil umschlägt...
Vielen Dank für deine Geduld und deinen wertvollen Tipps.
Für mich ist das Thema damit erst mal abgeschlossen.

mfg
Ernst
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E einfache Frage zu paintComponent und Graphics AWT, Swing, JavaFX & SWT 7
L Einfache Layout Frage für Applet -> Was mache ich bloss falsch? AWT, Swing, JavaFX & SWT 2
E Swing Einfache Frage zu JMenu AWT, Swing, JavaFX & SWT 4
E Einfache Frage zu GridBagLayout AWT, Swing, JavaFX & SWT 30
E einfache Frage zu invokeLater() AWT, Swing, JavaFX & SWT 4
E Einfache Frage zu GridLayout AWT, Swing, JavaFX & SWT 35
M einfache Frage über SWT GUI-Programmierung AWT, Swing, JavaFX & SWT 3
S Einfache Thread-Frage AWT, Swing, JavaFX & SWT 3
G Einfache Frage Panel AWT, Swing, JavaFX & SWT 5
Jose05 einfache GUI mit schwarzem Feld AWT, Swing, JavaFX & SWT 12
X JavaFX Einfache FX Application, aber wie alte Features umgehen? AWT, Swing, JavaFX & SWT 10
B AWT einfache Stoppuhr -Verbesserungsvorschläge AWT, Swing, JavaFX & SWT 2
E Warum macht die einfache Animation einen kleinen Fehler? AWT, Swing, JavaFX & SWT 14
A Einfache Benutzeroberfläche wie realisieren? AWT, Swing, JavaFX & SWT 6
P Swing Einfache Eingabe in JTextfield wird nicht ausgegeben AWT, Swing, JavaFX & SWT 3
E EINFACHE Verständnisfrage zu repaint(), paintComponent(), usw. AWT, Swing, JavaFX & SWT 16
V Swing Einfache Graphen-Lib? AWT, Swing, JavaFX & SWT 2
A Swing einfache fragen zu frame AWT, Swing, JavaFX & SWT 10
iLoveTheInternet Einfache Grafikausgabe AWT, Swing, JavaFX & SWT 2
B Einfache jpg-Bilder anzeigen AWT, Swing, JavaFX & SWT 8
H einfache Buttonanzeige AWT, Swing, JavaFX & SWT 2
M Einfache Möglichkeit einen Login Dialog zu bauen? AWT, Swing, JavaFX & SWT 1
G Einfache Text formatierung? Wie? AWT, Swing, JavaFX & SWT 4
O Suche einfache Möglichkeit zum Speichern AWT, Swing, JavaFX & SWT 21
E Frage zum Schieberegler JSlider AWT, Swing, JavaFX & SWT 5
thor_norsk Java - Allgemeine - Frage AWT, Swing, JavaFX & SWT 14
thor_norsk Allgemeine Frage AWT, Swing, JavaFX & SWT 10
M Frage zu Java Bundesligaverwaltung AWT, Swing, JavaFX & SWT 7
thor_norsk Allgemeine Frage AWT, Swing, JavaFX & SWT 9
E Frage zum Textfeld AWT, Swing, JavaFX & SWT 8
H Swing JMenu aufgeklappt oder nicht - Wie frage ich das ab? AWT, Swing, JavaFX & SWT 5
pkm Frage wegen java.lang.IllegalStateException bei DocumentListener AWT, Swing, JavaFX & SWT 4
D Frage zu ActionListenern und AvtionEvents AWT, Swing, JavaFX & SWT 2
ralfb1105 JavaFX Daten zwischen Controllern austauschen- neue Frage AWT, Swing, JavaFX & SWT 7
F JavaFX Frage zum Logging AWT, Swing, JavaFX & SWT 6
E Prinzip: wie man Ereignisse in einer GUI verarbeit. Frage zum Design? AWT, Swing, JavaFX & SWT 10
ralfb1105 Swing Frage zu SwingWorker Verhalten bei cancel() AWT, Swing, JavaFX & SWT 2
J Frage zu setuserdata AWT, Swing, JavaFX & SWT 1
N Frage zu ListView AWT, Swing, JavaFX & SWT 11
L 2D-Grafik Frage zu Ellipse2D.Double, Abfrage, ob Punkt enthalten ist funktioniert nicht AWT, Swing, JavaFX & SWT 3
T Frage zu GUI - Button soll Objekt erfassen AWT, Swing, JavaFX & SWT 2
J Event Handling Frage zu der Funktion addActionListener AWT, Swing, JavaFX & SWT 2
J Frage zur objektorentierten Swing Programmierung AWT, Swing, JavaFX & SWT 10
T JavaFX Frage zum FX-Loader AWT, Swing, JavaFX & SWT 3
B drawRect Frage und Aufgabenstellung AWT, Swing, JavaFX & SWT 10
fLooojava GridLayout - Frage bezüglich Kachelgröße AWT, Swing, JavaFX & SWT 5
S Frage zu java.awt.EventQueue AWT, Swing, JavaFX & SWT 1
J Frage zu Java Projekt [2D Game] AWT, Swing, JavaFX & SWT 3
M Swing Grundlegende Frage zu SWING mit WindowBuilder AWT, Swing, JavaFX & SWT 11
M Frage zum Loggen von Fehlern AWT, Swing, JavaFX & SWT 3
T Swing API Frage zu Verzeichnisbäumen und JTree AWT, Swing, JavaFX & SWT 1
M Thread-Frage in SWT AWT, Swing, JavaFX & SWT 1
Q Cursor Frage AWT, Swing, JavaFX & SWT 8
W JavaFX TableView frage AWT, Swing, JavaFX & SWT 5
H Taschenrechnerprojekt in Javafx - Frage zu den Buttons in FXML AWT, Swing, JavaFX & SWT 1
I Grundsätzliche Frage zu ItemListener AWT, Swing, JavaFX & SWT 11
X Kurze Frage zu JPopup AWT, Swing, JavaFX & SWT 3
D Swing [Frage] ComboBox + Label AWT, Swing, JavaFX & SWT 3
D Frage zu JFrame und Graphics AWT, Swing, JavaFX & SWT 4
J Swing Frage zur Vorgehensweise (JTable?, JLabels?) AWT, Swing, JavaFX & SWT 8
S Frage zu Jtable / CellEditor AWT, Swing, JavaFX & SWT 1
kaoZ Frage zum einfügen von Componenten AWT, Swing, JavaFX & SWT 14
N Swing JTable anfänger frage AWT, Swing, JavaFX & SWT 2
S GridBagLayout-Frage AWT, Swing, JavaFX & SWT 1
V 2D-Grafik Frage zum Graphics Objekt AWT, Swing, JavaFX & SWT 2
F Swing JComboBox - Frage zur Größe AWT, Swing, JavaFX & SWT 11
G noch eine Frage zum EventDispachThread AWT, Swing, JavaFX & SWT 4
D MVC Frage AWT, Swing, JavaFX & SWT 6
Z Flackern trotz Offscreen Image / Doublebuffer, (+ Frage zu Pixelvergleich) AWT, Swing, JavaFX & SWT 25
GianaSisters 2D-Grafik BufferedImage.getSubimage - Frage AWT, Swing, JavaFX & SWT 7
M Frage zu KeyListener bzgl. JApplet AWT, Swing, JavaFX & SWT 3
M Frage zu Threads AWT, Swing, JavaFX & SWT 3
N Swing JComboBox Frage AWT, Swing, JavaFX & SWT 5
Luk10 g.drawString funktioniert nicht + Frage zur Text-Rendering Qualität AWT, Swing, JavaFX & SWT 7
Luk10 Frage zu Farb-Komposition AWT, Swing, JavaFX & SWT 9
K Gui Layout Frage AWT, Swing, JavaFX & SWT 5
V SWT Import Wizard - frage zur WizardPage AWT, Swing, JavaFX & SWT 5
N Swing Frage JXMapviewer AWT, Swing, JavaFX & SWT 4
GUI-Programmer Wieder ne Layout Frage AWT, Swing, JavaFX & SWT 11
GUI-Programmer LayoutManager Kurze Layout Frage - eine komponente mittig? AWT, Swing, JavaFX & SWT 5
lumo SWT Zeichnen bescheunigen bzw eine allg. Frage AWT, Swing, JavaFX & SWT 8
H Frage zu übergebenem Vector bzw. Boolean AWT, Swing, JavaFX & SWT 3
C 2D-Grafik BufferedImage laden, Frage zum Code AWT, Swing, JavaFX & SWT 2
VfL_Freak Swing Frage zu "new JPasswordField( 10 )" AWT, Swing, JavaFX & SWT 6
H Frage zu WindowBuilder Pro AWT, Swing, JavaFX & SWT 3
C Frage/Problem mit Jpanel AWT, Swing, JavaFX & SWT 4
S Frage zu TextArea AWT, Swing, JavaFX & SWT 2
GUI-Programmer Zeichnen in Swing - Frage AWT, Swing, JavaFX & SWT 6
Luk10 Frage zu Mouseevents AWT, Swing, JavaFX & SWT 7
J Refreshing Swing Frage AWT, Swing, JavaFX & SWT 10
F Frage zu Event KeyTyped bei jPanel AWT, Swing, JavaFX & SWT 4
A Frage zu StringBuilder AWT, Swing, JavaFX & SWT 2
S allg. Frage zur GUI-Architektur AWT, Swing, JavaFX & SWT 5
A Frage zu JDialog AWT, Swing, JavaFX & SWT 3
A Frage zur Methode matches() AWT, Swing, JavaFX & SWT 2
P LayoutManager Verständnis-Frage GridBagLayout AWT, Swing, JavaFX & SWT 7
H Allgemeine Frage zu Grafikfähigkeiten von Java AWT, Swing, JavaFX & SWT 24
D Repaint Frage, Design Frage AWT, Swing, JavaFX & SWT 2
Jats Frage zu JLabel & JTextField AWT, Swing, JavaFX & SWT 4
Y frage zu BufferedImage AWT, Swing, JavaFX & SWT 7

Ähnliche Java Themen

Neue Themen


Oben