I have been searching for some days on internet a way to make flow charts(pie and vertical) using html and css, but I didn't find anything.Did someone make these types of charts in html and css and could help me ?
Finally I found a way to do this charts but I want the values to be the values computed on servlet side.For vertical pie is working but for pie chart no(nothing displayed).Also I want the scale to be at my max value (("${sumC}")=2000),now it is at 60.
Could anyone hep me with thos problems?
Thank you very much!
Here is my servlet code:
public class ListaCumparaturi extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try{
...
request.setAttribute("sumG", sumG);
request.setAttribute("sumCa", sumCa);
request.setAttribute("sumP", sumP);
request.setAttribute("sumC", sumC);
}
catch (Exception e2)
{
e2.printStackTrace();
}
finally
{
out.close();
}
}
}
Here is the js code:
<form action= "listacumparaturi" method="get">
<canvas width="1000" height="1000" id="myCanvas"></canvas>
var x= "${sumC}" ;
var y= "${sumG}" ; var z= "${sumP}" ; var w= "${sumCa}" ; total = "${sumT}";
var vertical = {
Calorii: x,
Grasimi: y,
Proteine: z,
Carbo: w
};
var data = Object.keys(vertical);
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";
total = "${sumT}";
color = ['red', 'blue', 'yellow','green','black'];
start = 0;
for (var i = 0; i < data.length; i++) {
ctx.fillRect((i * 60) + 50, 100, 10, -(vertical[data[i]]));
ctx.font = "9px Arial";
ctx.fillText(data[i], (i * 60) + 51, 112);
ctx.fillText((700 * i), 30, ((20 * -i) + 100));
ctx.beginPath();
ctx.moveTo(600, 150);
ctx.arc(600, 150, 150, start, start +
(Math.PI * 2 * (vertical[data[i]] / total)), false);
ctx.lineTo(600, 150);
ctx.fillStyle = color[i];
ctx.fill();
start += Math.PI * 2 * (vertical[data[i]] / total);
}
</script>
</form>
It is possible to build customm charts with HTML and CSS3 canvas.
I have created one sample codepen URL for reference.
http://codepen.io/nagasai/pen/EyjJLy
You can update your own data and build start charts from there
HTML:
Javascript:
//sample data object
var vertical = {
a: 10,
b: 20,
c: 40
};
var data = Object.keys(vertical);
total = 0;
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";
for (var i = 0; i < data.length; i++) {
total = total + vertical[data[i]];
}
color = ['red', 'blue', 'yellow'];
start = 0;
for (var i = 0; i < data.length; i++) {
ctx.fillRect((i * 60) + 50, 100, 10, -(vertical[data[i]]));
ctx.font = "9px Arial";
ctx.fillText(data[i], (i * 60) + 51, 112);
ctx.fillText((20 * i), 30, ((20 * -i) + 100));
ctx.beginPath();
ctx.moveTo(600, 150);
ctx.arc(600, 150, 150, start, start +
(Math.PI * 2 * (vertical[data[i]] / total)), false);
ctx.lineTo(600, 150);
ctx.fillStyle = color[i];
ctx.fill();
start += Math.PI * 2 * (vertical[data[i]] / total);
}
Hope this is helpful for you :)
Related
I am trying to create Android App with chart with variable line stroke width like this one in the link.
I have tried to realize it with MPAndroidChart. Override drawCubicBezier method in LineChartRenderer class and to set dynamically setStrokeWidth on Paint. But nothing happens. Probably my knowledge is not enough to do it.
Can you help me how to achieve a different line thickness or if there is another chart library that has such functionality?
This is how I set my new Renderer
chart2.setRenderer(new myLineChartRenderer(chart2, chart2.getAnimator(), chart2.getViewPortHandler()));
This is the class
public class myLineChartRenderer extends LineChartRenderer {
public myLineChartRenderer(LineChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
#Override
protected void drawCubicBezier(ILineDataSet dataSet) {
Path mPath = new Path();
ArrayList<Path> mPaths = new ArrayList<Path>();
mRenderPaint.setAntiAlias(true);
mRenderPaint.setDither(true);
mRenderPaint.setStyle(Paint.Style.STROKE);
mRenderPaint.setStrokeJoin(Paint.Join.ROUND);
mRenderPaint.setStrokeCap(Paint.Cap.ROUND);
//mRenderPaint.setStrokeWidth(STROKE_WIDTH);
float phaseY = mAnimator.getPhaseY();
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mXBounds.set(mChart, dataSet);
float intensity = dataSet.getCubicIntensity();
cubicPath.reset();
if (mXBounds.range >= 1) {
float prevDx = 0f;
float prevDy = 0f;
float curDx = 0f;
float curDy = 0f;
// Take an extra point from the left, and an extra from the right.
// That's because we need 4 points for a cubic bezier (cubic=4), otherwise we get lines moving and doing weird stuff on the edges of the chart.
// So in the starting `prev` and `cur`, go -2, -1
// And in the `lastIndex`, add +1
final int firstIndex = mXBounds.min + 1;
final int lastIndex = mXBounds.min + mXBounds.range;
Entry prevPrev;
Entry prev = dataSet.getEntryForIndex(Math.max(firstIndex - 2, 0));
Entry cur = dataSet.getEntryForIndex(Math.max(firstIndex - 1, 0));
Entry next = cur;
int nextIndex = -1;
if (cur == null) return;
// let the spline start
cubicPath.moveTo(cur.getX(), cur.getY() * phaseY);
mPath.moveTo(cur.getX(), cur.getY() * phaseY);
for (int j = mXBounds.min + 1; j <= mXBounds.range + mXBounds.min; j++) {
prevPrev = prev;
prev = cur;
cur = nextIndex == j ? next : dataSet.getEntryForIndex(j);
nextIndex = j + 1 < dataSet.getEntryCount() ? j + 1 : j;
next = dataSet.getEntryForIndex(nextIndex);
prevDx = (cur.getX() - prevPrev.getX()) * intensity;
prevDy = (cur.getY() - prevPrev.getY()) * intensity;
curDx = (next.getX() - prev.getX()) * intensity;
curDy = (next.getY() - prev.getY()) * intensity;
cubicPath.cubicTo(prev.getX() + prevDx, (prev.getY() + prevDy) * phaseY,
cur.getX() - curDx,
(cur.getY() - curDy) * phaseY, cur.getX(), cur.getY() * phaseY);
mPath.cubicTo(prev.getX() + prevDx, (prev.getY() + prevDy) * phaseY,
cur.getX() - curDx,
(cur.getY() - curDy) * phaseY, cur.getX(), cur.getY() * phaseY);
mPaths.add(mPath);
// Log.i("Curve", (prev.getX() + prevDx)+" | "+ ((prev.getY() + prevDy) * phaseY)+" | "+ (cur.getX() - curDx)+" | "+ ((cur.getY() - curDy) * phaseY)+" | "+ cur.getX()+" | "+ (cur.getY() * phaseY));
}
}
// if filled is enabled, close the path
if (dataSet.isDrawFilledEnabled()) {
cubicFillPath.reset();
cubicFillPath.addPath(cubicPath);
//drawCubicFill(mBitmapCanvas, dataSet, cubicFillPath, trans, mXBounds);
}
mRenderPaint.setColor(dataSet.getColor());
mRenderPaint.setStyle(Paint.Style.STROKE);
trans.pathValueToPixel(cubicPath);
//mBitmapCanvas.drawPath(cubicPath, mRenderPaint);
for(int i=0; i<mPaths.size();i++)
{
mRenderPaint.setStrokeWidth(i+30);
mBitmapCanvas.drawPath(mPaths.get(i), mRenderPaint);
}
mRenderPaint.setPathEffect(null);
}
}
I tried to divide the path into separate parts and change the thickness of the line while drawing them, but the result is totally wrong.
I try to create a little game in java but I'm in trouble.
When I draw a map, I'm not able to display the characters without overwrite the titlesets of the squares.
My goal is to be able to display many pictures on the same square (like the titleset of the grass, the character and a tree), so I have to deal with the transparency of my pictures (this is not the problem) and the layer (it is the problem).
So how can I display an image on another image?
How can I explain to java that I need to display this image on or under another image?
This is my source code. I don't know is that can help you. Your help can be really helpfull for me if you give me a clue or a function who is able to manage the layers. That is useless to rewrite all the code for me x)
This program is not complete, I use it only for test my program right now. I know that he refresh two times the map so he overwrite the square of the character (and he have many others littles glitchs), but that is not the purpose of my question. I try to done my game by step!
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class Window extends Thread
{
private static JFrame window = new JFrame("game");
public void run()
{
Map map = new Map();
Characters characters = new Characters();
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setSize(Settings.sizeX, Settings.sizeY);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setVisible(true);
map.start();
characters.start();
}
private static void reload() throws Exception
{
SwingUtilities.updateComponentTreeUI(window);
}
private static class Map extends Thread
{
private int numberSquareX = Settings.sizeX / 20 + 1;
private int numberSquareY = Settings.sizeY / 20 + 1;
private JLabel square[][] = new JLabel[numberSquareX][numberSquareY];
public void run()
{
for (int x = 0, y = 0; y < numberSquareY; x++)
{
square[x][y] = new JLabel(new ImageIcon("grass_1.png"));
square[x][y].setBounds(x * 20, y * 20, 20, 20);
window.add(square[x][y]);
if (x == numberSquareX - 1)
{
y++;
x = -1;
}
}
square[numberSquareX - 1][numberSquareY - 1] = new JLabel(new ImageIcon("grass_1.png"));
square[numberSquareX - 1][numberSquareY - 1].setBounds(numberSquareX * 20, numberSquareY * 20, 20, 20);
window.add(square[numberSquareX - 1][numberSquareY - 1]);
try
{
reload();
}
catch (Exception e)
{
}
return;
}
}
private class Characters extends Thread
{
private JLabel square[][] = new JLabel[1][1];
public void run()
{
square[0][0] = new JLabel(new ImageIcon("character_1.png"));
square[0][0].setBounds(Test.posX, Test.posX, 20, 20);
window.add(square[0][0]);
try
{
reload();
}
catch (Exception e)
{
}
return;
}
}
}
I have already find this subjects: How to use JLayered Pane to display an image on top of another image? and this one Best practice for creating a composite image output for Java Swing but they haven't really help me...
I continue to search the answer. If I find it, I will come back for post it here.
Solved.
Thanks to MadProgrammer for his comments.
Render the title map to a BufferedImage, either in it's entirety or based on the available viewable area, which ever is more efficient. Paint this to the screen, then paint your character on top it – MadProgrammer
In 15+ years of professional Java/Swing development, I've never found a need to use SwingUtilities.updateComponentTreeUI(window);, instead, simply call repaint on the component which is responsible for renderer the output, I'm pretty sure, you'll find this more efficient. – MadProgrammer
Swing is also a single threaded environment AND is not thread safe, you should NOT be update the UI from outside of the context of the Event Dispatching Thread, as this will setup a race condition and could result in unwanted and difficult to resolve graphical issues. – MadProgrammer
Hint. JLabel is a descendent of Container, which means it can contain other components ;) – MadProgrammer
Thanks a lot MadProgrammer! So I have replace SwingUtilities.updateComponentTreeUI(window) by window.repaint(). You had right for the Thread safe, my map had some bugs but I wasn't able to find where they was from. And what about the BufferedImage? If I create two BufferedImage, the last one can be automatically on the top of the first one? Or I just want to render the title map to a BufferedImage (so I am limited by 2 layers)? – Celine
It will depend on what it is you want to achieve. Using BufferedImages gives you complete control over the placement of the images and yes, one can be rendered over the other, painting is like a artists canvas, as you add things to it, they are added on top of what is already there, BUT, you might find it easier to add a JLabel to another JLabel - just remember, JLabel doesn't have a layout manager by default – MadProgrammer
Code example:
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class Window extends Thread
{
private static JFrame window = new JFrame("game");
private int numberSquareX = Settings.sizeX / 20 + 1;
private int numberSquareY = Settings.sizeY / 20 + 1;
private JLabel titlesetLayer1[][] = new JLabel[numberSquareX][numberSquareY];
private JLabel titlesetLayer2[] = new JLabel[1];
private JLabel titlesetLayer3[] = new JLabel[1];
private JLabel titlesetLayer4[] = new JLabel[0];
private JLabel titlesetLayer5[] = new JLabel[0];
private JLabel characters[] = new JLabel[2];
public void run()
{
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setSize(Settings.sizeX, Settings.sizeY);
window.setLocationRelativeTo(null);
window.setResizable(false);
// draw layer5 (on the layer4)
// draw layer4 (on the layer3)
// draw layer3 (on the characters)
titlesetLayer3[0] = new JLabel(new ImageIcon("tree_1.png"));
titlesetLayer3[0].setBounds(130, 120, 126, 160);
window.add(titlesetLayer3[0]);
// draw the charaters
characters[1] = new JLabel(new ImageIcon("character_1.png"));
characters[1].setBounds(600, 500, 100, 100);
window.add(characters[1]);
characters[0] = new JLabel(new ImageIcon("character_1.png"));
characters[0].setBounds(100, 100, 100, 100);
window.add(characters[0]);
// draw layer2 (under the characters)
titlesetLayer2[0] = new JLabel(new ImageIcon("tree_1.png"));
titlesetLayer2[0].setBounds(570, 400, 126, 160);
window.add(titlesetLayer2[0]);
// draw layer1 (under the layer2)
for (int x = 0, y = 0; y < numberSquareY; x++)
{
titlesetLayer1[x][y] = new JLabel(new ImageIcon("grass_1.png"));
titlesetLayer1[x][y].setBounds(x * 20, y * 20, 20, 20);
window.add(titlesetLayer1[x][y]);
if (x == numberSquareX - 1)
{
y++;
x = -1;
}
}
titlesetLayer1[numberSquareX - 1][numberSquareY - 1] = new JLabel(new ImageIcon("grass_1.png"));
titlesetLayer1[numberSquareX - 1][numberSquareY - 1].setBounds(numberSquareX * 20, numberSquareY * 20, 20, 20);
window.add(titlesetLayer1[numberSquareX - 1][numberSquareY - 1]);
window.setVisible(true);
// window.repaint();
}
}
Screen capture:
1
Another solution is to use JLayeredPane!
JLayeredPane layers = new JLayeredPane();
layers.add(tilesetsUnderCharacter, 0); // Layer 0
layers.add(character, 1); // Layer 1
layers.add(tilesetsOnCharacter, 2); // Layer 2
frame.setContentPane(layers);
Code example:
private void init()
{
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
frame.setSize(Settings.getX(), Settings.getY());
frame.setResizable(false);
frame.setLocationRelativeTo(null);
for (int i = 0; i < y ; i++)
{
for (int j = 0; j < x; j++)
{
for (int k = 0; k < tilesetsOnCharactersSize; k++)
{
tilesetsOnCharacters[i][j][k] = new javax.swing.JLabel(new javax.swing.ImageIcon(Resources.getTileset(Maps.getMapTileset(mapNumber, 1, k, i, j))));
tilesetsOnCharacters[i][j][k].setBounds(j * tilesetX, i * tilesetY, tilesetX, tilesetY);
map.add(tilesetsOnCharacters[i][j][k], 4);
}
for (int k = 0; k < tilesetsUnderCharactersSize; k++)
{
tilesetsUnderCharacters[i][j][k] = new javax.swing.JLabel(new javax.swing.ImageIcon(Resources.getTileset(Maps.getMapTileset(mapNumber, 0, k, i, j))));
tilesetsUnderCharacters[i][j][k].setBounds(j * tilesetX, i * tilesetY, tilesetX, tilesetY);
map.add(tilesetsUnderCharacters[i][j][k], 0);
}
for (int k = 0; k < mapAttributeSize; k++)
{
if (Maps.getMapTileset(mapNumber, 2, k, i, j) == 1)
{
blocked[i][j] = true;
}
}
}
}
for (int i = 0; i < charactersNumber; i++)
{
characters[i] = new Character(0, 0, 64, 64, 0, 0, 0, 0, 5);
tilesetsCharacters[i] = new javax.swing.JLabel(new javax.swing.ImageIcon(Characters.getCharacter(characters[i].getCharacterSkin(), characters[i].getDirection())));
tilesetsCharacters[i].setBounds(characters[i].getX(), characters[i].getY(), characters[i].getSizeX(), characters[i].getSizeY());
map.add(tilesetsCharacters[i], 1);
charactersRender[i] = false;
}
frame.addKeyListener(new java.awt.event.KeyAdapter()
{
#Override
public void keyTyped(java.awt.event.KeyEvent keyEvent)
{
}
#Override
public void keyPressed(java.awt.event.KeyEvent keyEvent)
{
if((keyEventInt = keyEvent.getKeyCode()) == java.awt.event.KeyEvent.VK_F)
{
right = true;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_S)
{
left = true;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_E)
{
up = true;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_D)
{
down = true;
}
}
#Override
public void keyReleased(java.awt.event.KeyEvent keyEvent)
{
if((keyEventInt = keyEvent.getKeyCode()) == java.awt.event.KeyEvent.VK_F)
{
right = false;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_S)
{
left = false;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_E)
{
up = false;
}
else if(keyEventInt == java.awt.event.KeyEvent.VK_D)
{
down = false;
}
}
});
frame.setContentPane(map);
frame.setVisible(true);
}
private void update()
{
if (exit && characters[0].getX() < x * tilesetX - characters[0].getSizeX() - characters[0].getMovementSpeed() && characters[0].getX() > 0 && characters[0].getY() > 0 && characters[0].getY() < y * tilesetY - characters[0].getSizeY() - characters[0].getMovementSpeed())
{
exit = false;
}
if (right && (exit || (characters[0].getX() < x * tilesetX - characters[0].getSizeX() - characters[0].getMovementSpeed() && !blocked[characters[0].getY() / tilesetY][(characters[0].getX() + characters[0].getSizeX() + characters[0].getMovementSpeed()) / tilesetX] && !blocked[(characters[0].getY() + characters[0].getSizeY()) / tilesetY][(characters[0].getX() + characters[0].getSizeX() + characters[0].getMovementSpeed()) / tilesetX])))
{
characters[0].right();
characters[0].setScaleX(5);
if (allowExitRight && characters[0].getX() > x * tilesetX - characters[0].getSizeX() - characters[0].getMovementSpeed() - 1)
exit = true;
charactersRender[0] = true;
}
if (left && (exit || (characters[0].getX() > 0 && !blocked[characters[0].getY() / tilesetY][(characters[0].getX() - characters[0].getMovementSpeed()) / tilesetX] && !blocked[(characters[0].getY() + characters[0].getSizeY()) / tilesetY][(characters[0].getX() - characters[0].getMovementSpeed()) / tilesetX])))
{
characters[0].left();
characters[0].setScaleX(-3);
if (allowExitLeft && characters[0].getX() <= 0)
exit = true;
charactersRender[0] = true;
}
if (jumped || up && (exit || (characters[0].getY() > 0 && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][characters[0].getX() / tilesetX] && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][(characters[0].getX() + characters[0].getSizeX()) / tilesetX])))
{
if (!jump)
{
characters[0].up();
characters[0].setScaleY(-3);
if (allowExitUp && characters[0].getY() <= 0)
exit = true;
charactersRender[0] = true;
}
else if (!jumped && !falling)
{
jumpCurrentDuration = jumpDuration;
jumped = true;
}
else if (--jumpCurrentDuration > 0)
{
if (exit || (characters[0].getY() > 0 && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][characters[0].getX() / tilesetX] && !blocked[(characters[0].getY() - characters[0].getMovementSpeed()) / tilesetY][(characters[0].getX() + characters[0].getSizeX()) / tilesetX]))
{
characters[0].up();
characters[0].setScaleY(-3);
if (allowExitUp && characters[0].getY() <= 0)
exit = true;
charactersRender[0] = true;
}
}
else
{
jumped = false;
}
}
if (((down && !jumped) || (gravity && !jumped)) && (exit || (characters[0].getY() < y * tilesetY - characters[0].getSizeY() - characters[0].getMovementSpeed() && !blocked[(characters[0].getY() + characters[0].getSizeY() + characters[0].getMovementSpeed()) / tilesetX][characters[0].getX() / tilesetX] && !blocked[(characters[0].getY() + characters[0].getSizeY() + characters[0].getMovementSpeed()) / tilesetY][(characters[0].getX() + characters[0].getSizeX()) / tilesetX])))
{
characters[0].down();
characters[0].setScaleY(5);
if (allowExitDown && characters[0].getY() > y * tilesetY - characters[0].getSizeY() - characters[0].getMovementSpeed())
exit = true;
if (jump)
falling = true;
charactersRender[0] = true;
}
else if (jump)
falling = false;
}
private void render()
{
for (int i = 0; i < charactersNumber; i++)
{
if (charactersRender[i])
{
tilesetsCharacters[i].setIcon(new javax.swing.ImageIcon(Characters.getCharacter(characters[i].getCharacterSkin(), characters[i].getDirection())));
tilesetsCharacters[i].setBounds(characters[i].getX() + characters[i].getScaleX(), characters[i].getY() + characters[i].getScaleY(), characters[i].getSizeX(), characters[i].getSizeY());
charactersRender[i] = false;
}
}
}
Screen Capture:
Edit: I also found a library called Slick2D who work with TiledMapEditor:
http://slick.ninjacave.com/
http://www.mapeditor.org/
How to setup Slick2D: How to install Slick2d?
How to use Slick2D and TiledMapEditor: Slick2D + Tiled cant load map
Where started: https://thejavablog.wordpress.com/2008/06/08/using-slick-2d-to-write-a-game/
Please help me anyone! I'm stuck!
I'm trying to compare value inserted in textfield and value shown in Captcha (image), if they match it will show alert('Yes!') otherwise alert('No!'). But when I trying to get session value of Captcha (request.getSession().getAttribute("captcha")) it gets previous value of it!
How to make sure that value of Catcha if the same as user sees on image?
Captcha.jsp:
<%# page import="java.util.*"%>
<%# page import="java.io.*"%>
<%# page import="javax.servlet.*"%>
<%# page import="javax.servlet.http.*"%>
<%# page import="java.awt.*"%>
<%# page import="java.awt.image.*"%>
<%# page import="javax.imageio.*"%>
<%# page import="java.awt.geom.*"%>
<%
String imageFormat = "jpg";
response.setContentType("image/" + imageFormat);
try {
// you can pass in fontSize, width, height via the request
Color backgroundColor = Color.red;
Color borderColor = Color.black;
Color textColor = Color.white;
Color circleColor = new Color(160, 160, 160);
Font textFont = new Font("Arial", Font.PLAIN, paramInt(request,
"fontSize", 24));
int charsToPrint = 6;
int width = paramInt(request, "width", 150);
int height = paramInt(request, "height", 80);
int circlesToDraw = 6;
float horizMargin = 20.0f;
float imageQuality = 0.95f; // max is 1.0 (this is for jpeg)
double rotationRange = 0.7; // this is radians
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, width, height);
// lets make some noisey circles
g.setColor(circleColor);
for (int i = 0; i < circlesToDraw; i++) {
int circleRadius = (int) (Math.random() * height / 2.0);
int circleX = (int) (Math.random() * width - circleRadius);
int circleY = (int) (Math.random() * height - circleRadius);
g.drawOval(circleX, circleY, circleRadius * 2,
circleRadius * 2);
}
g.setColor(textColor);
g.setFont(textFont);
FontMetrics fontMetrics = g.getFontMetrics();
int maxAdvance = fontMetrics.getMaxAdvance();
int fontHeight = fontMetrics.getHeight();
// i removed 1 and l and i because there are confusing to users...
// Z, z, and N also get confusing when rotated
// 0, O, and o are also confusing...
// lowercase G looks a lot like a 9 so i killed it
// this should ideally be done for every language...
// i like controlling the characters though because it helps prevent confusion
String elegibleChars = "ABCDEFGHJKLMPQRSTUVWXYabcdefhjkmnpqrstuvwxy23456789";
char[] chars = elegibleChars.toCharArray();
float spaceForLetters = -horizMargin * 2 + width;
float spacePerChar = spaceForLetters / (charsToPrint - 1.0f);
AffineTransform transform = g.getTransform();
StringBuffer finalString = new StringBuffer();
for (int i = 0; i < charsToPrint; i++) {
double randomValue = Math.random();
int randomIndex = (int) Math.round(randomValue * (chars.length - 1));
char characterToShow = chars[randomIndex];
finalString.append(characterToShow);
// this is a separate canvas used for the character so that
// we can rotate it independently
int charImageWidth = maxAdvance * 2;
int charImageHeight = fontHeight * 2;
int charWidth = fontMetrics.charWidth(characterToShow);
int charDim = Math.max(maxAdvance, fontHeight);
int halfCharDim = (int) (charDim / 2);
BufferedImage charImage = new BufferedImage(charDim,
charDim, BufferedImage.TYPE_INT_ARGB);
Graphics2D charGraphics = charImage.createGraphics();
charGraphics.translate(halfCharDim, halfCharDim);
double angle = (Math.random() - 0.5) * rotationRange;
charGraphics.transform(AffineTransform
.getRotateInstance(angle));
charGraphics.translate(-halfCharDim, -halfCharDim);
charGraphics.setColor(textColor);
charGraphics.setFont(textFont);
int charX = (int) (0.5 * charDim - 0.5 * charWidth);
charGraphics
.drawString(
"" + characterToShow,
charX,
(int) ((charDim - fontMetrics.getAscent()) / 2 + fontMetrics
.getAscent()));
float x = horizMargin + spacePerChar * (i) - charDim / 2.0f;
int y = (int) ((height - charDim) / 2);
//System.out.println("x=" + x + " height=" + height + " charDim=" + charDim + " y=" + y + " advance=" + maxAdvance + " fontHeight=" + fontHeight + " ascent=" + fontMetrics.getAscent());
g.drawImage(charImage, (int) x, y, charDim, charDim, null, null);
charGraphics.dispose();
}
// let's do the border
g.setColor(borderColor);
g.drawRect(0, 0, width - 1, height - 1);
//Write the image as a jpg
Iterator iter = ImageIO
.getImageWritersByFormatName(imageFormat);
if (iter.hasNext()) {
ImageWriter writer = (ImageWriter) iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
if (imageFormat.equalsIgnoreCase("jpg")
|| imageFormat.equalsIgnoreCase("jpeg")) {
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(imageQuality);
}
writer.setOutput(ImageIO.createImageOutputStream(response.getOutputStream()));
IIOImage imageIO = new IIOImage(bufferedImage, null, null);
writer.write(null, imageIO, iwp);
} else {
throw new RuntimeException("no encoder found for jsp");
}
// set session
request.getSession().setAttribute("captcha", finalString.toString());
System.out.println("Captcha.jsp: "+request.getSession().getAttribute("captcha"));//for console output
out.clear();
out = pageContext.pushBody();
g.dispose();
} catch (IOException ioe) {
throw new RuntimeException("Unable to build image", ioe);
}
%>
<%!public static String paramString(HttpServletRequest request,
String paramName, String defaultString) {
return request.getParameter(paramName) != null ? request
.getParameter(paramName) : defaultString;
}
public static int paramInt(HttpServletRequest request, String paramName,
int defaultInt) {
return request.getParameter(paramName) != null ? Integer
.parseInt(request.getParameter(paramName)) : defaultInt;
}%>
To set sesion I'm using - request.getSession().setAttribute("captcha", finalString.toString());
ValidateCapture.jsp:
<html>
<head>
<script type="text/javascript">
function ValidateCaptcha(){
<%String captcha=(String)request.getSession().getAttribute("captcha");%>
var answer = document.getElementById("answer").value;
var captcha = '<%=captcha%>';
if(answer==captcha){
alert('Yes');
}
else{
alert('No');
}
}
</script>
</head>
<body>
<img src="Captcha.jsp"/>
<input id="answer" type="text">
<input type="button" value="Submit" onclick="ValidateCaptcha();">
<%System.out.println("ValidateCapture.jsp: "+request.getSession().getAttribute("captcha"));%> <!--for console output-->
</body>
To get session I'm using - request.getSession().getAttribute("captcha");
Console Output:
i saw the code. expecially about set session. i thought you shouldn't set attribute value. First, session invalid just when The browser closed or no-operation time up 30 mins in tomcat configuration file. however,you didn't close your browser,you will get the same captcha with previous value of it. so, we can do this,follow the code: request.setAttribute("captcha", finalString.toString());//set value and request.getAttribute("captcha");//get value
like this.we will get different captcha values when we click the pictures.Request Object also changed. why do this? because when "Request" to server and server responsed later,request Object invalid. next request will produce new request object.just this,good luck.
I would like to implement a "grid view" of pixmaps. This is how I would like the UI to behave: You click a button and it shows a QGraphicsView with a QGraphicsScene (done) and then I would like to show all of my QPixmaps in a grid view. I don't actually want to see a grid I just want to organize the pixmaps like 10 columns (pixmaps) pr. row, and then a 10px whitespace in-between each pixmap. (not done). How would this be implemented?
EDIT: Here's what I've done so far (which produces the outcome described in the second comment)
public SpriteScene() {
super(0, 0, 800, 500);
QPixmap[] sprites = GUI.getWInterface().sprites;
List<QPixmap> l = Arrays.asList(sprites);
Iterator<QPixmap> i = l.iterator();
int rows = 10 / sprites.length;
boolean isDone = false;
for(int y = 0; y < rows; y++) {
for(int x = 0; x < 10; x++) {
if(i.hasNext()) {
QGraphicsPixmapItem pixmap = addPixmap(i.next());
pixmap.setPos(x * 64 + 10 , y * 64 + 10);
} else {
isDone = true;
break;
}
}
if(isDone) {
break;
}
}
}
SpriteScene extends QGraphicsScene and is being added to a QGraphicsView like this:
spriteView = new QGraphicsView(new SpriteScene(), this);
spriteView.setGeometry(0, 35, 850, 550);
spriteView.setAlignment(new Qt.AlignmentFlag[]{Qt.AlignmentFlag.AlignLeft, Qt.AlignmentFlag.AlignTop});
spriteView.hide();
Oh and by the way each pixmap is 64x64px :)
pixmap.setPos(x * 64 + 10 , y * 64 + 10);
Write that down on paper for the first few values:
x = 0, y = 0 => pos = ( 10, 10)
x = 1, y = 0 => pos = ( 74, 10)
x = 2, y = 0 => pos = (138, 10)
There's only 64 pixel different between each successive x offset. You need 74 pixels - the size of the pixmap plus the size of the border.
Set a few variables for your image with, height, horizontal and vertical spacing, and your code should look like:
pixmap.setPos(x * (width+hspacing) + offsetx, y * (height+vspacing) + offsety);
The offsetx/y would probably look nicer if they were half the respective spacing valued to get the grid "centered".
I have a calculator that is suposed to figure the volume and the results come back as "0"
JButton btnCalculateVlmn = new JButton("Calculate Hot Tub Volume");
btnCalculateVlmn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
double width = 0, length = 0, depth = 0, volume = 0;
String lengthString, widthString, depthString;
lengthString = hotTubLengthText.getText();
widthString = hotTubWidthText.getText();
depthString = hotTubDepthText.getText();
try
{
if (rdbtnRoundTub.isSelected())
{
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
}
else
{
volume = Math.PI * Math.pow(length * width, 2)
* depth;
}
DecimalFormat formatter = new DecimalFormat("#,###,###.###");
hotTubVolumeText.setText("" + formatter.format(volume));
}
catch (NumberFormatException e)
{
labelTubStatus
.setText("Fill in all fields");
}
}
});
btnCalculateVlmn.setBounds(20, 200, 180, 20);
hotTubs.add(btnCalculateVlmn);
JButton Exit = new JButton("Exit");
Exit.setBounds(220, 200, 80, 20);
Exit.addActionListener(this);
hotTubs.add(Exit);
}
depth is declared as 0 and never overwritten... so the volume is always 0.
I guess you should do something like:
...
double width = 0, length = 0, depth = 0, volume = 0;
String lengthString, widthString, depthString;
lengthString = hotTubLengthText.getText();
widthString = hotTubWidthText.getText();
depthString = hotTubDepthText.getText();
depth = Double.valueOf(depthString);
length = Double.valueOf(lengthString);
width = Double.valueOf(widthString);
....
You forgot to convert the strings (lengthString, widthString and depthString) to doubles and assign them to your variables (length, width and depth).
you have depth = 0 and
anything * 0 = 0
you forgot to convert your strings from the input fields to double.
you get 0 as result because you set length and width to 0
In both branches of your main if condition your expressions ending * depth. However this depth variable seems to be set to 0 and not set to anything else. So volume will always be 0 since whatever you multiply by 0 will be 0.
Maybe you've wanted to use depthString. Something like this:
depth = Integer.parseInt(depthString);
if (rdbtnRoundTub.isSelected())
{
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
}
else
{
volume = Math.PI * Math.pow(length * width, 2) * depth;
}