Post by chriscrawford on May 24, 2016 14:13:38 GMT -8
I have struggled against a problem for a week now and gotten nowhere. I attach the relevant code below. For now, the problem is not getting it to scroll. The problem is getting it to paint properly. The paintComponent() method does indeed paint correctly into the JScrollPane. However, the correct image appears only for a fraction of a second; it is immediately painted over with the background color of the JScrollPane: yellow.
Ignore method draw(); it is not used in the initial drawing of the JScrollPane. The fundamental problem is this:
Why does the JScrollPane draw its background AFTER it has drawn its foreground?
Any help would be much appreciated.
Ignore method draw(); it is not used in the initial drawing of the JScrollPane. The fundamental problem is this:
Why does the JScrollPane draw its background AFTER it has drawn its foreground?
Any help would be much appreciated.
package Engine.enginePackage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import com.storytron.enginecommon.Utils;
import com.storytron.uber.Actor;
import com.storytron.uber.Deikto;
import com.storytron.uber.Sentence;
import com.storytron.uber.Verb;
import com.storytron.uber.Verb.WSData;
public class HistoryBookDisplay extends JScrollPane {
// This class draws the scroll pane on the right side of the window.
private static final long serialVersionUID = 1L;
static final Color transparent = new Color(0,0,0,0); // transparency color
static final int PaneWidth = 570; // width of the scroll pane
static final int PaneHeight = 740; // height of the scroll pane
private static final int CharacterDisplayY = 30; // initial offset for painting
private static final int GlyphSize = 75; // standard size of the glyphs being painted
private Image mainBuffer; // the offscreen image into which I paint
Graphics2D offScreenG2D, mainBufferG2D;
Engine tEngine; // needed for looking up past events
// these next images are for "graphical housekeeping".
private BufferedImage upLink, downLink, rightLink, leftLink, lightener, darkener;
private SmallSympolSet smallSympols; // the complete set of sympols
private int currentBottom, previousBottom; // markers for scrolling.
private int selectedCharacter; // index of the character whom the player has clicked on
private boolean isMouseDown; // a simple flag
private Deikto dk; // the main dictionary of SympolTalk, used to look up sympols.
private BufferedImage[] numbers, certainties; // the sympol images for numbers and certainties
// ************************************************************
public HistoryBookDisplay(Engine theEngine, Deikto tdk) {
setVisible(false); // make sure it doesn't attempt to paint until AFTER it has been initialized
tEngine = theEngine;
dk = tdk;
smallSympols = new SmallSympolSet();
setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
setPreferredSize(new Dimension(PaneWidth, PaneHeight));
setBackground(Color.black);
getViewport().setBackground(Color.yellow);
upLink = readImage("UpLink");
downLink = readImage("DownLink");
leftLink = readImage("LeftLink");
rightLink = readImage("RightLink");
lightener = readImage("lightener");
darkener = readImage("darkener");
currentBottom = 0;
previousBottom = 0;
selectedCharacter = 0;
isMouseDown = false;
setVisible(true); // OK, now we can permit painting
}
// ************************************************************
public void draw(int newSentence, boolean isNewLine) {
// this method is currently nonfunctional and not used. It will be important later.
boolean isTwoRowsHigh = false;
if (!isNewLine)
currentBottom = previousBottom;
Sentence zSentence = tEngine.getHistoryBookPage(newSentence);
Verb zVerb = tEngine.getDeikto().getVerb(zSentence.getIWord(Sentence.Verb));
int offset = 0;
if (zSentence.getIWord(0) != 1)
offset = PaneWidth/2;
int j = 0;
while (zSentence.getIWord(j)>=0) {
if (zVerb.isVisible(j)) {
int x = 20 + GlyphSize * zVerb.getSentenceColumn(j) + offset;
int y = currentBottom + GlyphSize * zVerb.getSentenceRow(j);
if (zVerb.getSentenceRow(j)>0)
isTwoRowsHigh = true;
int k = zSentence.getIWord(j);
BufferedImage testImage = smallSympols.getGlyph(tEngine.getDeikto().getLabelByDataType(zSentence.getWordSocket(j).getType(), k));
offScreenG2D.drawImage(testImage, x, y, transparent, null);
WSData wsd = zVerb.getWSData(j);
if (wsd.outArrow[WSData.UP])
offScreenG2D.drawImage(upLink, x+22, y-15, transparent, null);
if (wsd.outArrow[WSData.DOWN])
offScreenG2D.drawImage(downLink, x+22, y+59, transparent, null);
if (wsd.outArrow[WSData.LEFT])
offScreenG2D.drawImage(leftLink, x-15, y+23, transparent, null);
if (wsd.outArrow[WSData.RIGHT])
offScreenG2D.drawImage(rightLink, x+60, y+23, transparent, null);
}
++j;
}
previousBottom = currentBottom;
currentBottom+=GlyphSize + 20;
if (isTwoRowsHigh)
currentBottom+=GlyphSize;
// repaint();
}
// ************************************************************
public void paintComponent(Graphics g){
// This paint method works. It's what happens AFTER it paints that trouble starts.
mainBuffer = createImage(PaneWidth, PaneHeight);
mainBufferG2D = (Graphics2D)mainBuffer.getGraphics();
mainBufferG2D.setColor(Color.blue); // testing the drawing onto the screen
mainBufferG2D.fillRect(0, 0, 300, 600);
// paint the sympols for the five characters onto the top of the panel
for (int i=2; i<6; ++i) {
String name = dk.getActor(i).getLabel();
mainBufferG2D.drawImage(smallSympols.getGlyph(name), (i-1)*GlyphSize, CharacterDisplayY, transparent, this);
if (i != selectedCharacter) { // lighten unselected characters
mainBufferG2D.drawImage(lightener,(i-1)*GlyphSize, CharacterDisplayY, transparent, this);
}
}
if (selectedCharacter>0) {
if (isMouseDown) // this darkens the character if the mouse is down on him
mainBufferG2D.drawImage(darkener,(selectedCharacter-1)*GlyphSize, CharacterDisplayY, transparent, this);
else { // this paints all the information about the selected character.
Actor selectedActor = dk.getActor(selectedCharacter);
// first draw auragon counts with certainties
for (int j=0; j<3; ++j) {
String sympolName = "";
switch (j) {
case 0: { sympolName = "Red"; break; }
case 1: { sympolName = "Green"; break; }
case 2: { sympolName = "Blue"; break; }
}
mainBufferG2D.drawImage(smallSympols.getGlyph(sympolName+"Auragon"), 100+GlyphSize/2, CharacterDisplayY+100+j*GlyphSize, transparent, this);
mainBufferG2D.drawImage(leftLink, 85+3*GlyphSize/2, CharacterDisplayY+100+j*GlyphSize+33, transparent, this);
int iTrait = dk.findActorTraitWord(sympolName+"Auragon");
float auragonCount = dk.getActor(1).getP(dk.getActorTraits().get(iTrait), selectedActor);
int iCount = (int)bounded2Real(auragonCount)+3;
mainBufferG2D.drawImage(numbers[iCount], 10+GlyphSize, CharacterDisplayY+100+j*GlyphSize, transparent, this);
mainBufferG2D.drawImage(leftLink, 85+5*GlyphSize/2, CharacterDisplayY+100+j*GlyphSize+33, transparent, this);
float certainty = dk.getActor(1).getU(dk.getActorTraits().get(iTrait), selectedActor);
int iCertainty = (int)(bounded2Real(certainty)+2.5f);
if (iCertainty < 0)
iCertainty = 0;
if (iCertainty > 5)
iCertainty = 5;
mainBufferG2D.drawImage(certainties[iCertainty], 100+5*GlyphSize/2, CharacterDisplayY+100+j*GlyphSize, transparent, this);
// Utils.displayDebuggingError(auragonCount+" "+(int)bounded2Real(auragonCount)+" "+certainty+" "+iCertainty);
}
// next draw P3 values with certainties
for (int j=0; j<3; ++j) {
String name = dk.getActor(1).getLabel();
mainBufferG2D.drawImage(smallSympols.getGlyph(name), 10+GlyphSize, 430+j*GlyphSize, transparent, this);
String sympolName = "";
switch (j) {
case 0: { sympolName = "powerful"; break; }
case 1: { sympolName = "honest"; break; }
case 2: { sympolName = "good"; break; }
}
mainBufferG2D.drawImage(smallSympols.getGlyph(sympolName), 10+2*GlyphSize, CharacterDisplayY+390+j*GlyphSize, transparent, this);
mainBufferG2D.drawImage(leftLink, -5+2*GlyphSize, CharacterDisplayY+390+j*GlyphSize+33, transparent, this);
int iTrait = dk.findActorTraitWord(sympolName)-2;
float p3Value = dk.getActor(1).getP3(iTrait, selectedCharacter, 1);
int iValue = (int)bounded2Real(p3Value)+3;
if (iValue < 0)
iValue = 0;
if (iValue > 6)
iValue = 6;
mainBufferG2D.drawImage(numbers[iValue], 10+3*GlyphSize, CharacterDisplayY+390+j*GlyphSize, transparent, this);
mainBufferG2D.drawImage(leftLink, -5+3*GlyphSize, CharacterDisplayY+390+j*GlyphSize+33, transparent, this);
float certainty = dk.getActor(1).getU3(iTrait, selectedCharacter, 1);
int iCertainty = (int)bounded2Real(certainty)+3;
if (iCertainty < 0)
iCertainty = 0;
if (iCertainty > 6)
iCertainty = 6;
mainBufferG2D.drawImage(certainties[iCertainty], 10+4*GlyphSize, CharacterDisplayY+390+j*GlyphSize, transparent, this);
mainBufferG2D.drawImage(leftLink, -5+4*GlyphSize, CharacterDisplayY+390+j*GlyphSize+33, transparent, this);
// Utils.displayDebuggingError(auragonCount+" "+(int)bounded2Real(auragonCount)+" "+certainty+" "+iCertainty);
}
}
}
getViewport().getGraphics().drawImage(mainBuffer, 0, 0, transparent, this);
// All the imagery painted in this method is drawn onto the panel by the above line.
// But it is immediately overwritten by the yellow background of the ViewPort.
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
float bounded2Real(float boundedNumber) {
if (boundedNumber > 0.0f) {
if (boundedNumber>Utils.MAXI_VALUE)
boundedNumber = Utils.MAXI_VALUE;
return (1.0f / (1.0f - boundedNumber)) -1.0f;
}
else
{
if (boundedNumber<Utils.MINI_VALUE)
boundedNumber = Utils.MINI_VALUE;
return 1.0f - (1.0f / (1.0f + boundedNumber));
}
}
// ************************************************************
// just a file-reading routine
private BufferedImage readImage(String fileName) {
BufferedImage bi=null;
String tName = System.getProperty("user.dir")+"/res/images/SmallSympols/"+fileName+".png";
try {
bi=ImageIO.read(new File(tName));
} catch (Exception e) {
System.out.println("Cannot find image: "+fileName); }
return bi;
}
// ************************************************************
}