I am trying to print a table to a piece of paper in a custom style, but only the column headers are printed on the page when I send it to the printer.
When using the same code to print to a JPanel, it works just fine.
I have been debugging like a madman, but all I've found is that a different Graphics is used when writing to a printer, and that it calculates the widths of the strings slightly differently, somehow, though I can't see how that should have an impact on what gets written or not.
I have been able to confirm that all the code is run, though.
The code that draws the headers:
private void drawColumnHeaders(Graphics2D g, PageFormat pf)
{
g.drawLine(columnWidths[0]-1, 0, columnWidths[0]-1, rowHeight);
drawText(g, 1, columnHeader[1]);
drawLineAround(g, 1);
drawText(g, 2, columnHeader[2]);
drawLineAround(g, 2);
etc...
...
g.translate(0, rowHeight);
}
The code that draws the rows:
private void drawRow(Graphics2D g, Konto konto, boolean kunAfstanden)
{
...
drawAccountNo(g, konto, 1);
etc...
...
g.translate(0, rowHeight);
}
...
private void drawAccountNo(Graphics2D g, Account account, int columnNo)
{
switch (account.getType())
{
case SUMACCOUNT:
drawLineBeneath(g, columnNo);
default:
drawText(g, columnNo, "" + account.getAccountNo());
break;
}
}
Utility methods:
private void drawText(Graphics2D g, int columnNo, String text)
{
int startX = calculatePosition(columnNo);
g.drawString(text, startX + lMargin, g.getFontMetrics().getAscent() + aMargin);
}
private void drawLineAround(Graphics2D g, int columnNo)
{
int startX = calculatePosition(columnNo);
drawLineBeneath(g, columnNo);
g.drawLine(startX + columnWidths[columnNo], 0, startX + columnWidths[columnNo], rowHeight);
}
...
private int calculatePosition(int columnNo)
{
int result = 0;
for (int i = 0; i < columnNo; i++)
{
result+= columnWidths[i];
}
return result;
}
Any help is appreciated.
Edit:
The code that controls the printing:
#Override
public int print(Graphics ga, PageFormat pf, int pageIndex) throws PrinterException
{
ga.setFont(normalFont);
Graphics2D g = (Graphics2D) ga;
if (!writeToPrinter)
{
pf = standardPF;
}
int returnMessage = -1;
int noOfRowsOnPage = 0;
calculateColumnWidths(g, pf);
//Calculates how many pages there will be:
calculateNoOfPages(g, pf);
if (pageIndex < noOfPages)
{
//Translates Graphics:
prepareGraphics(g, pf);
//The parts that do show up:
drawHeader(g, pf);
drawStart(g, pf);
drawColumnHeaders(g, pf);
while (returnMessage == -1)
{
try
{
if (accounts.get(iReached).getType().t() != TypeAccount.NEWPAGE.t() && possibleRows > noOfRowsOnPage)
{
//The part that doesn't (even though the code is reached):
drawRow(g, accounts.get(iReached));
noOfRowsOnPage++;
}
else
{
//If the page isn't empty, go to the next page
if (noOfRowsOnPage > 0)
{
returnMessage = PAGE_EXISTS;
}
}
iReached++;
}
catch (IndexOutOfBoundsException e)
{
returnMessage = PAGE_EXISTS;
}
}
drawFooter(g, pf, false);
}
else
{
returnMessage = NO_SUCH_PAGE;
}
return returnMessage;
}
The initialization of the PageFormat used:
standardPF = new PageFormat();
standardPF.setOrientation(PageFormat.PORTRAIT);
Paper paper = new Paper();
paper.setImageableArea(30, 30, 535, 780);
paper.setSize(595.44, 841.68);
standardPF.setPaper(paper);
Related
Good afternoon, I am using stm32 Blue Pill on USB raised com - port, development environment "IAR".
The problem is the following, when I connect through the application, the number "3"
does not change to the number "50" after the arrow, but on the contrary is shown next !
See Figure 1.2. I work under the protocol.
How do you achieve this?
I'm using the controlP5 library and cp5.addNumberbox.
Data in "IAR".
int Bullet = 50; // variable for result
sprintf((char *)str, "(,%d,-Ђ",Bullet); // sending a command with data to stm32.
In the code of the Displaydata tab, the line "case 40" is the symbol (
The command can also be sent through the terminal using a virtual com port.
Command: (, 50 ,! Figure 3.
I'll have to lay out the whole little project for you to check it out.
Com_Interface1:
import processing.serial.*;
import controlP5.*;
ControlP5 cp5;
DropdownList serialPortsList;
Serial serialPort;
final int BAUD_RATE = 9600;
char parity = 'N';
int dataBits = 8;
float stopBits = 1.0;
public void setup() {
background(50);
size(700, 420, P3D);
surface.setTitle("TEST");
surface.setResizable(false);
setupUI();
smooth();
frameRate(30);
writeOutgioing[lengthmas-1]=1;
String[] portNames = Serial.list();
//serialPort.clear(); // Why does not it work?
for (int i = 0; i < portNames.length; i++) serialPortsList.addItem(portNames[i], i);
}
public void toplug (int theValue)
{ // Start button on click sends a commad 1.
println("Button click events: "+theValue);
strata =!strata;
if (!strata) {
connection.setLabel("Пуск");
serialPort.dispose();
Vin.setText("Voltage K.V - ");
inputPULI.setLabel("Bullet");
} else {
connection.setLabel("СТОП");
serialports((int)serialPortsList.getValue());
writeOutgioing[0]=1;
writeOut();
}
}
public void serialports(int theValue) {
try {
serialPort = new Serial(this, Serial.list()[theValue], BAUD_RATE, parity, dataBits, stopBits);
serialPort.bufferUntil('\n');
println("COM connected: "+ Serial.list()[theValue] );
/*Send.unlock();
connection.unlock();*/ // locking buttons in applications if not connected via rs-232.
}
catch(Exception e) {
System.err.println("Error opening serial port" + Serial.list()[theValue]);
e.printStackTrace();
}
}
/*void controlEvent(ControlEvent event){
println(event.getController().getName(),"changed value to",event.getValue(),"inputPULI = ",PUL,"inputNapryzenieKV = ",NapryzenieKV,"CheckBoxuvum= ",
UV/UM,"P4 = ",std2,);
}*/
Displaydata:
void Displaydata() {
switch(x)
{
case 20:
// What to write?
// label(testRead[1]+" Мин."); // ImageButton
// min=testRead[1];
break;
case 30:
// What to write?
// P4.setText("std2"+ testRead[1]); // CheckBox
break;
case 40:
inputPULI.setLabel("Bullet: " + testRead[1] );
break;
case 70:
inputNapryzenieKV.setLabel("Voltage: " + testRead[1] );
break;
case 60:
Vin.setText("Voltage K.V: " + testRead[1] + " " + testRead[2]);
break;
case 50:
// What to write?
//CheckBoxuvum.setText("UV/UM - " +testRead[1] ); // RadioButton
break;
default:
println("DisplayData(): no case selected.");
break; // technically not necessary, but I like my switches tidy
}
}
GUI:
int PUL;
float NapryzenieKV;
boolean strata=false;
ImageButton button;
Numberbox inputPULI;
Numberbox inputNapryzenieKV;
RadioButton CheckBoxuvum;
CheckBox P4;
Textlabel Vin;
Button connection;
Button Send;
public void setupUI()
{
cp5 = new ControlP5(this);
PFont fontn = createFont("Times New Roman", 18);
PFont p = createFont("Times New Roman", 18);
ControlFont font=new
ControlFont(p);
cp5.setFont(font);
connection = cp5.addButton("toplug")
.setCaptionLabel("ПУСК")
.setPosition(387, 30)
.setSize(150, 30);
serialPortsList = cp5.addDropdownList("Порт")
.setPosition(130, 30)
.setSize(150, 200)
.setItemHeight(30)
.setBarHeight(30);
PImage[] imgs = {loadImage("button101.png"), loadImage("button102.png"), loadImage("button103.png")};
Send = cp5.addButton("toapply")
//.setCaptionLabel("Apply")
//.setPosition(510, 370)
//.setSize(150, 30);
.setPosition(590, 330)
.setImages(imgs)
.updateSize();
//.lock()
Vin = cp5.addTextlabel("naprazhenie kondencatora")
.setText("Voltage K.V")
.setFont(p)
.setColor(color(#00ffff))
.setPosition(45, 320);
CheckBoxuvum = cp5.addRadioButton("UV/UM")
.setPosition(155, 360)
.setSize(15, 15)
.setColorActive(color(255))
.setItemsPerRow(2)
.setSpacingColumn(85)
.addItem("+", 1)
.addItem("-", 2);
P4 = cp5.addCheckBox("std2")
.setPosition(150, 190)
.setSize(15, 15)
.setItemsPerRow(1)
.setSpacingColumn(30)
.setSpacingRow(20)
.addItem("Check", 2);
inputPULI = cp5.addNumberbox("PUL")
.setLabel("Bullet")
.setPosition(220, 220)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setDirection(Controller.HORIZONTAL)
.setRange(1, 199)
.setValue(3);
Label labelinputPULI = inputPULI.getCaptionLabel();
labelinputPULI.setFont(font);
labelinputPULI.setColor(color(#00ffff));
labelinputPULI.toUpperCase(false);
labelinputPULI.setText("Bullet");
labelinputPULI.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputPULI.getStyle().setPaddingLeft(-25);
inputNapryzenieKV = cp5.addNumberbox("NapryzenieKV")
.setLabel("Voltage")
.setPosition(150, 270)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setMin(25)
.setMax(99)
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(25);
Label labelinputNapryzenieKV = inputNapryzenieKV.getCaptionLabel();
labelinputNapryzenieKV.setFont(font);
labelinputNapryzenieKV.setColor(color(#00ffff));
labelinputNapryzenieKV.toUpperCase(false);
labelinputNapryzenieKV.setText("Напряжение");
labelinputNapryzenieKV.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputNapryzenieKV.getStyle().setPaddingLeft(-45);
textFont(fontn);
{
// button dimensions
int w = 99;
int h = 25;
// test with generated images
button = new ImageButton(555, 230, w, h,
new PImage[]{
loadImage("0.png"), // off
loadImage("1.png"), // 10
loadImage("2.png"), // 20
loadImage("3.png"), // 30
loadImage("4.png"), // 40
loadImage("5.png"), // 50
loadImage("6.png"), // 60
});
}
}
void mousePressed() {
button.mousePressed(mouseX, mouseY);
println(button.min);
}
// test images to represent loaded state images
PImage getImage(int w, int h, int c) {
PImage img = createImage(w, h, RGB);
java.util.Arrays.fill(img.pixels, c);
img.updatePixels();
return img;
}
// make a custom image button class
class ImageButton {
// minutes is the data it stores
int min = 0;
// images for each state
PImage[] stateImages;
// which image to display
int stateIndex;
// position
int x, y;
// dimensions: width , height
int w, h;
// text to display
String label = "ВЫКЛ";
ImageButton(int x, int y, int w, int h, PImage[] stateImages) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.stateImages = stateImages;
}
void mousePressed(int mx, int my) {
// check the cursor is within the button bounds
boolean isOver = ((mx >= x && mx <= x + w) && // check horizontal
(my >= y && my <= y + h) ); // check vertical
if (isOver) {
min += 10;
stateIndex++;
if (min>60) {
min = 0;
stateIndex = 0;
label = "ВЫКЛ";
} else {
label = (str(min) + "Мин");
}
}
}
void draw() {
// if the images and index are valid
if (stateImages != null && stateIndex < stateImages.length) {
image(stateImages[stateIndex], x, y, w, h);
} else {
println("error displaying button state image");
println("stateImages: ");
printArray(stateImages);
println("stateIndex: " + stateIndex);
}
// display text
//text(label, x + 17, y + h - 8);
}
}
void controlEvent(ControlEvent theEvent) {
if (theEvent.isFrom(CheckBoxuvum)) {
//myColorBackground = 0;
print("got an event from "+CheckBoxuvum.getName()+"\t\n");
// checkbox uses arrayValue to store the state of
// individual checkbox-items. usage:
println(CheckBoxuvum.getArrayValue());
int col = 0;
for (int i=0; i<CheckBoxuvum.getArrayValue().length; i++) {
int n = (int)CheckBoxuvum.getArrayValue()[i];
print(n);
if (n==1) {
//myColorBackground += CheckBoxuvum.getItem(i).internalValue();
}
}
println();
}
if (theEvent.isGroup()) {
// check if the Event was triggered from a ControlGroup
println("event from group : "+theEvent.getGroup().getValue()+" from "+theEvent.getGroup());
} else if (theEvent.isController()) {
println("event from controller : "+theEvent.getController().getValue()+" from "+theEvent.getController());
}
}
Protocol:
int lengthmas = 7;
int RC = 0x21; // -128 separating byte в java
int[] writeOutgioing = new int[lengthmas];
String incomingData= null;
String outgoingData=null;
String[] testRead = new String[lengthmas];
int x;
void readInc() {
while ( serialPort.available() > 0)
{
incomingData = serialPort.readStringUntil(RC);
testRead = split (incomingData, ',' );
if (testRead != null)
{
x = (int) testRead[0].charAt(0);
Displaydata();
}
}
}
void writeOut() {
outgoingData=str(writeOutgioing[0])+str(writeOutgioing[1])+str(writeOutgioing[2])+str(writeOutgioing[3])+str(writeOutgioing[4])+str(writeOutgioing[5])+str(writeOutgioing[6]); // sending data as a string.
serialPort.write(outgoingData);
}
Senddata:
public void toapply()
{
}
loop:
void draw()
{
background(50);
button.draw();
if (strata)
{
readInc();
}
}
code:
inputPULI = cp5.addNumberbox("PUL")
.setLabel("Bullet")
.setPosition(220, 220)
.setSize(80, 30)
.setColorValue(0xffffff00)
.setFont(p)
.setScrollSensitivity(1.1)
.setDirection(Controller.HORIZONTAL)
.setRange(1, 199)
.setValue(3);
Label labelinputPULI = inputPULI.getCaptionLabel();
labelinputPULI.setFont(font);
labelinputPULI.setColor(color(#00ffff));
labelinputPULI.toUpperCase(false);
labelinputPULI.setText("Bullet");
labelinputPULI.align(ControlP5.LEFT_OUTSIDE, CENTER);
labelinputPULI.getStyle().setPaddingLeft(-25);
I figured it out myself, I had to write setLabel->setValueLabel
example
What I've tried.
Please help me.. I really don't know.
I think it's related to canvas class.
CustomLineChartRenderer
It seems to me that color is not filled according to x value, but color is filled at once.
It's hard because I'm not used to canvas. Please help me.
Here are three methods for drawing lines and filling in colors.
#Override
protected void drawLinearFill(Canvas c, ILineDataSet dataSet, Transformer trans, XBounds bounds) {
final Path filled = mGenerateFilledPathBuffer;
final int startingIndex = bounds.min;
final int endingIndex = bounds.range + bounds.min;
final int indexInterval = 128;
int currentStartIndex = 0;
int currentEndIndex = indexInterval;
int iterations = 0;
// Doing this iteratively in order to avoid OutOfMemory errors that can happen on large bounds sets.
do {
currentStartIndex = startingIndex + (iterations * indexInterval);
currentEndIndex = currentStartIndex + indexInterval;
currentEndIndex = currentEndIndex > endingIndex ? endingIndex : currentEndIndex;
if (currentStartIndex <= currentEndIndex) {
generateFilledPath(dataSet, currentStartIndex, currentEndIndex, filled);
trans.pathValueToPixel(filled);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, filled, drawable);
} else {
//////Here part of applying color
drawFilledPath(c, filled, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
iterations++;
} while (currentStartIndex <= currentEndIndex);
}
#Override
protected void drawFilledPath(Canvas c, Path filledPath, int fillColor, int fillAlpha) {
int color = (fillAlpha << 24) | (fillColor & 0xffffff);
if (clipPathSupported()) {
Log.e("clipPathSupported","1");
int save = c.save();
c.clipPath(filledPath);
c.drawColor(color);
c.restoreToCount(save);
} else {
Log.e("clipPathSupported","2");
// save
Paint.Style previous = mRenderPaint.getStyle();
int previousColor = mRenderPaint.getColor();
// set
mRenderPaint.setStyle(Paint.Style.FILL);
mRenderPaint.setColor(color);
c.drawPath(filledPath, mRenderPaint);
// restore
mRenderPaint.setColor(previousColor);
mRenderPaint.setStyle(previous);
}
}
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float fillMin = dataSet.getFillFormatter().getFillLinePosition(dataSet, mChart);
final float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), fillMin);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = entry;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
if (isDrawSteppedEnabled) {
filled.lineTo(currentEntry.getX(), previousEntry.getY() * phaseY);
}
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
previousEntry = currentEntry;
}
// close up
if (currentEntry != null) {
filled.lineTo(currentEntry.getX(), fillMin);
}
filled.close();
}
You can use shader, same :
mRenderPaint.shader = LinearGradient(fromX, fromY, toX, toY, color1,
color2,
Shader.TileMode.CLAMP)
The goal of the current program is to create a line, of varying thickness, between two points in a window frame. So far, so good.
Next, I would like the program to recognize that the user has made a selection from the JComboBox.
This post, and the code, have been updated. (a) the itemStateChanged method was removed. It was not executed, and so, did not need to be in the program. (b) the actionPerformed method was updated to update whenever any of the objects were modified. (c) the color choice was implemented in perhaps one of the ugliest switch/case statements ever. (there must be a better way). And (d) I implemented the suggestion from Itamar Green, regarding the definition of the JComboBox. Thank you.
What don't I know?
Notes: Java 8.111. O/S: Windows 8.1. IDE: Ecilpse Java EE 4.6.0
All responses towards improving the code or the question are gratefully accepted.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class ThickPen extends JApplet implements ActionListener
{
private static final long serialVersionUID = 1L;
JLabel xStartLabel = new JLabel("X Start");
JLabel yStartLabel = new JLabel("Y Start");
JLabel xStopLabel = new JLabel("X Stop");
JLabel yStopLabel = new JLabel("Y Stop");
JLabel thickLabel = new JLabel("Thickness");
JComboBox<String> myColour;
String theColour = "black";
TextField xStartField = new TextField(4);
int xStart = 0;
TextField yStartField = new TextField(4);
int yStart = 0;
TextField xStopField = new TextField(4);
int xStop = 0;
TextField yStopField = new TextField(4);
int yStop = 0;
TextField thicknessField = new TextField(4);
int thick = 0;
String[] colourString = {"black","blue","cyan","darkgray","gray","green",
"lightGray","magenta","orange","pink","red","white","yellow"};
int theIndex = 0;
public void init()
{
setSize(550,500);
Container content = getContentPane();
setLayout(new FlowLayout());
xStartField.addActionListener(this);
yStartField.addActionListener(this);
xStopField.addActionListener(this);
yStopField.addActionListener(this);
thicknessField.addActionListener(this);
add(xStartLabel);
add(xStartField);
add(yStartLabel);
add(yStartField);
add(xStopLabel);
add(xStopField);
add(yStopLabel);
add(yStopField);
add(thickLabel);
add(thicknessField);
myColour = new JComboBox<String>(colourString);
// JComboBox<String> myColour = new JComboBox<String>(colourString);
myColour.setSelectedIndex(0); // start with black
myColour.addActionListener(this);
add(myColour);
content.setBackground(Color.white);
content.setForeground(Color.black);
}
public void paint(Graphics g)
{
super.paint(g);
Dimension d = getSize();
int fullWidth = d.width;
int fullHeight = d.height;
int deltaX = 0;
int deltaY = 0;
boolean xAxis = false;
System.out.println("So far Start x y: "+xStart+" "+yStart+" color: "+theColour);
if (xStart < 1 || xStart > fullWidth
|| yStart < 1 || yStart > fullHeight
|| xStop < 1 || xStop > fullWidth
|| yStop < 1 || yStop > fullHeight
|| thick < 1 || thick > fullHeight || thick > fullWidth) {
String outStr = "Start and stop numbers must be within this window frame";
String outStr2 = "Current width: "+fullWidth+" height: "+fullHeight;
g.setColor(Color.white);
g.fillRoundRect(d.width/4, d.height/4, 300, 40, 4, 4);
g.setColor(Color.red);
g.drawString(outStr, d.width/4+10, d.height/4+15);
g.drawString(outStr2, d.width/4+10, d.height/4+30);
g.drawString("The index: "+theIndex, d.width/4, 300);
} else {
g.drawString("", d.width/4, 260);
deltaX = Math.abs(xStart - xStop); // determine absolute delta of two Xs
deltaY = Math.abs(yStart - yStop); // determine absolute delta of two Ys
if (deltaX > deltaY) // make line thickness based on x axis if
xAxis = false; // the x axis has the most 'room'.
else // else, use the y axis.
xAxis = true;
pickAColour(g, theColour);
drawMyLine(g, xStart, yStart, xStop, yStop, thick, xAxis);
}
g.drawString("The index: "+theIndex, d.width/4, 300);
g.drawString("The color "+ theColour, d.width/4, 330);
}
public void drawMyLine(Graphics g, int xStart, int yStart,
int xStop, int yStop, int thick, boolean xAxis)
{
int count = 0;
while (count < thick)
{
g.drawLine(xStart, yStart, xStop, yStop);
count++;
if (xAxis) {
xStart++;
xStop++;
} else {
yStart++;
yStop++;
}
}
}
public void pickAColour(Graphics g, String theColour)
{
switch (theColour) {
case "black" :
g.setColor(Color.black);
break;
case "blue" :
g.setColor(Color.blue);
break;
case "cyan" :
g.setColor(Color.cyan);
break;
case "darkgray" :
g.setColor(Color.darkGray);
break;
case "gray" :
g.setColor(Color.gray);
break;
case "green" :
g.setColor(Color.green);
break;
case "lightGray" :
g.setColor(Color.lightGray);
break;
case "magenta" :
g.setColor(Color.magenta);
break;
case "orange" :
g.setColor(Color.orange);
break;
case "pink" :
g.setColor(Color.pink);
break;
case "red" :
g.setColor(Color.red);
break;
case "white" :
g.setColor(Color.white);
break;
case "yellow" :
g.setColor(Color.yellow);
break;
} // end of case statement
} // end of pickAColour
public void actionPerformed (ActionEvent ae)
{
Object source=ae.getSource();
// xStart
// if (source==xStartField)
// {
try {
xStart=Integer.parseInt(
xStartField.getText());
}
catch (NumberFormatException x) {
xStart= -1;
}
// }
// yStart
// else if (source==yStartField)
// {
try {
yStart=Integer.parseInt(
yStartField.getText());
}
catch (NumberFormatException x) {
yStart= -1;
}
// }
// xStop
// else if (source==xStopField)
// {
try {
xStop=Integer.parseInt(
xStopField.getText());
}
catch (NumberFormatException x) {
xStop= -1;
}
// }
// yStop
// else if (source==yStopField)
// {
try {
yStop=Integer.parseInt(
yStopField.getText());
}
catch (NumberFormatException x) {
yStop= -1;
}
// }
// thickness
// else if (source==thicknessField)
// {
try {
thick=Integer.parseInt(
thicknessField.getText());
}
catch (NumberFormatException x) {
thick= -1;
}
// } else {
if (source==myColour) {
JComboBox<String> cb = (JComboBox<String>)ae.getSource();
// String theColour = (String)cb.getSelectedItem(); ///can;
// Integer theIndex = (int)cb.getSelectedIndex();
theColour = (String)cb.getSelectedItem();
theIndex = (int)cb.getSelectedIndex();
}
// }
repaint();
} // end of ActionEvent
} // end of class
Simply put this
myColour = new JComboBox<String>(colourString);
instead of this
JComboBox<String> myColour = new JComboBox<String>(colourString);
in your init method.
The problem is the difference between the myColour defined here (in member section)
JComboBox<String> myColour;
and the one created in the init(). You are initializing the one in the Init but not the one in the member section, so when you are trying to use myColour in actionPreformed, Java is trying to call methods from a reference with no object.
I am making a simple rpg game and i have been trying to add enemies to the game. It is loading in the enemy find with all it's stats, but when i try to render it, i get Exception in thread "Thread-2" java.lang.NullPointerException
at com.hosfordryan.tileRPG.entities.Enemy.render(Enemy.java:52)
at com.hosfordryan.tileRPG.Game.render(Game.java:134)
at com.hosfordryan.tileRPG.Game.run(Game.java:103)
at java.lang.Thread.run(Unknown Source)
. I have used JOptionPanes to confirm that the enemies are saving in the arrayList, so that can't be it. Code for reading in enemy is:
public static void loadEnemies() {
Scanner qwe;
try {
qwe = new Scanner(new File("enemyStats.txt"));
while (qwe.hasNextLine()) {
String name = qwe.nextLine();
String origin = qwe.nextLine();
String weapon = qwe.nextLine();
String gear = qwe.nextLine();
String spec = qwe.nextLine();
int hp = qwe.nextInt();
int att = qwe.nextInt();
int def = qwe.nextInt();
int randX = (int) (Math.random()*(20*SCALE*TILESIZE)); //Give random x coordinate
int randY = (int) (Math.random()*(20*SCALE*TILESIZE)); //Give random y coordinate
if(qwe.hasNextLine()){
qwe.nextLine();
}
enemies.add(new Enemy(randX,randY,im,name,origin,weapon,gear,spec,hp,att,def)); //adds enemy into arrayList
String temp = "";
temp+=enemies.get(enemies.size()-1).getName()+"\n"+enemies.get(enemies.size()-1).getRx(); //checking if saving into arrayList correctly
JOptionPane.showMessageDialog(null, temp);
}
for(int i = 0; i < enemies.size();i++){ //adds enemy to arrayList to be rendered
enemiestoRend.add( new Enemy(enemies.get(i).getRx(),enemies.get(i).getRy(),im,enemies.get(i).getName(),enemies.get(i).getOrigin(),enemies.get(i).getWeapon(),enemies.get(i).getGear(),enemies.get(i).getSpecialMove(),enemies.get(i).gethp()
,enemies.get(i).getAttack(),enemies.get(i).getDefense()));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Code for rendering:
public void render(Graphics g){
g.drawImage(im.enemy, this.x*Game.TILESIZE * Game.SCALE, this.x*Game.TILESIZE * Game.SCALE, Game.TILESIZE * Game.SCALE,
Game.TILESIZE * Game.SCALE, null);
}
Render method in main which renders everything:
public void render(){
BufferStrategy bs = this.getBufferStrategy();
if (bs==null) {
createBufferStrategy(3);
return;
}
Graphics g= bs.getDrawGraphics();
//Render Here
else if(Player.l1){
l1.render(g);
}
for(int i = 0; i < enemies.size();i++){
enemies.get(i).render(g);
}
for(int i = 0; i < enemiestoRend.size();i++){
enemiestoRend.get(i).render(g); //problem here
}
player.render(g);
//End Render
g.dispose();
bs.show();
}
I am trying to develop a hex editor in which the panel for editor is provided with key listeners and the input through keyboard is converted into corresponding input. The problem however is regarding the saving the coverted input.only one key stroke value is converted at a time as for now. I would like to use this converted input() in a string as a bunch and use it for other purposes. I tried to save converted text in a byte array but it is returning the first value I typed irrespective of what the input afterwards is.
package gui.hex;
import javax.swing.*;
import cryptool.Test;
import java.awt.*;
import java.awt.event.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
public class JHexEditorASCII extends JComponent implements MouseListener,
KeyListener {
private static final long serialVersionUID = 5636121664420538046L;
private JHexEditor he;
private static CharsetEncoder encoder = Charset.forName("UTF-8")
.newEncoder();
public static String modifiedText;
public static byte temp[];
public static byte[] getTemp() {
return temp;
}
public void setTemp(byte[] temp) {
this.temp = temp;
}
protected JHexEditorASCII(JHexEditor he) {
this.he = he;
addMouseListener(this);
addKeyListener(this);
addFocusListener(he);
}
public Dimension getPreferredSize() {
debug("getPreferredSize()");
return getMinimumSize();
}
public Dimension getMinimumSize() {
debug("getMinimumSize()");
Dimension d = new Dimension();
FontMetrics fn = getFontMetrics(JHexEditor.font);
int h = fn.getHeight();
int nl = he.getLines();
d.setSize((fn.stringWidth(" ") + 1) * (16) + (he.border * 2) + 1, h
* nl + (he.border * 2) + 1);
return d;
}
public void paint(Graphics g) {
debug("paint(" + g + ")");
debug("cursor=" + he.cursor + " buff.length=" + he.buff.length);
Dimension d = getMinimumSize();
// sets the color to the background.
g.setColor(Color.orange);
g.fillRect(0, 0, d.width, d.height);
g.setColor(Color.black);
g.setFont(JHexEditor.font);
// ascii data
int ini = he.getInitial() * 16;
int fin = ini + (he.getLines() * 16);
if (fin > he.buff.length)
fin = he.buff.length;
int x = 0;
int y = 0;
for (int n = ini; n < fin; n++) {
if (n == he.cursor) {
// sets color for the focus cursor it used to be in blue color.
g.setColor(Color.red);
if (hasFocus())
he.background(g, x, y, 1);
else
he.table(g, x, y, 1);
if (hasFocus())
g.setColor(Color.white);
else
g.setColor(Color.black);
} else {
g.setColor(Color.black);
}
// builds a character object
String s;
if (encoder.isLegalReplacement(new byte[] { he.buff[n] }))
s = "" + new Character((char) he.buff[n]);
else
s = ".";
// compares the input supplied
// if ((he.buff[n] < 20) || (he.buff[n] > 126))
// converts the input entered into string
// s = ".";
// displaying of the text goes here.
// displays the input
System.out.println("the typed in string is:" + s);
temp = s.getBytes();
setTemp(temp);
setModifiedText(s);
he.printString(g, s, (x++), y);
if (x == 16) {
x = 0;
y++;
}
}
}
private void debug(String s) {
if (he.DEBUG)
System.out.println("JHexEditorASCII ==> " + s);
}
public void dispaly(Graphics g) {
int x = 0;
int y = 0;
he.printString(g, Test.getK(), (x++), y);
if (x == 16) {
x = 0;
y++;
}
}
// calculate the position of the mouse
public int calculateMousePosition(int x, int y) {
FontMetrics fn = getFontMetrics(JHexEditor.font);
x = x / (fn.stringWidth(" ") + 1);
y = y / fn.getHeight();
debug("x=" + x + " ,y=" + y);
return x + ((y + he.getInitial()) * 16);
}
// mouselistener
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
// double clicked
he.setNewTextListener.actionPerformed(new ActionEvent(this, 0,
"NEWASCII"));
}
debug("mouseClicked(" + e + ")");
he.cursor = calculateMousePosition(e.getX(), e.getY());
this.requestFocus();
he.repaint();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// KeyListener
public void keyTyped(KeyEvent e) {
debug("keyTyped(" + e + ")");
// only add content, if buffer is large enough
if (he.buff.length > he.cursor) {
he.buff[he.cursor] = (byte) e.getKeyChar();
if (he.cursor != (he.buff.length - 1))
he.cursor++;
// change this
// System.out.println( he.buff.toString());
he.repaint();
}
}
public void keyPressed(KeyEvent e) {
debug("keyPressed(" + e + ")");
he.keyPressed(e);
}
public void keyReleased(KeyEvent e) {
debug("keyReleased(" + e + ")");
}
public boolean isFocusTraversable() {
return true;
}
public static String getModifiedText() {
return modifiedText;
}
public void setModifiedText(String modifiedText) {
this.modifiedText = modifiedText;
}
}
develop a hex editor (encoder.isLegalReplacement...)
use JTextField with DocumentFilter, or easiest could be JFormatterTextField instead of paint chars by using paint() to JComponent
use paintComponent (instead of paint()) for Swing JComponents
add DocumentListener to the JTextField with DocumentFilter or JFormatterTextField
interesting way could be to built / prepare / create a ArrayList of hex () and to use AutoComplete JTextField