i have my class declared:
public class myRightPanel extends JPanel
then i override the paintComponent of my super class like this:
public void paintComponent(Graphics g){
super.paintComponents(g);
//Draw bunch of things here
}
Now it turns out i also need a method which takes in two integer(x,y) parameters and adds something to my already drawn myRightPanel at that coordinates. How do i do this when i have already overridden my paintComponent()?
Store the x,y as a Point as an attribute of the class so it is accessible within the paint method. Call repaint().
You need to use the Graphics object to draw any content you want.
For example:
public void paintComponent(Graphics g){
super.paintComponents(g);
g.drawString("Hello test", 0, 0);
}
I recommend reading Java 2D tutorial:
http://docs.oracle.com/javase/tutorial/2d/index.html
Related
I want create Text elements (com.itextpdf.layout.element.Text) with different kind of additional graphical effects, for example a drop shadow or adding some kind of texture on the glyphs. (see DropShadow some 3D Effect)
What is the best way of achiving this?
The best idea i had so far, is using the clipping Text Rendering mode. (Defined in PDF 32000-1 9.3.6; com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants.TextRenderingMode). Drawing the Text as clipping boundary and the apply some kind of Texture or drawing an additional shadow "layer". However the clipping path is restored to the state before text drawing with canvas.restoreState(), which is called at the end in com.itextpdf.layout.renderer.TextRender#draw. Extending this to a custom TextRenderer could work, but the draw function is a big one with some calls to private functions of TextRenderer.
Any adivces for other possible methods?
I think in general customization of that level will require quite come code anyway. Completely overriding draw may indeed not work because some private implementation details are not exposed to the public. One option is of course to duplicate those implementation details into your custom renderer.
Another idea is to plug into the PdfCanvas which does low-level drawing. You can create your own wrapper like the following one and delegate all operations to the PdfCanvas instance you wrap around except a couple of "interesting" operations where you will customize the logic and apply some styling:
private static class PdfCanvasWrapper extends PdfCanvas {
private PdfCanvas delegate;
public PdfCanvasWrapper(PdfCanvas wrapped) {
super(wrapped.getContentStream(), wrapped.getResources(), wrapped.getDocument());
this.delegate = wrapped;
}
// "Interesting" methods
#Override
public PdfCanvas endText() {
delegate.endText();
delegate.setFillColor(ColorConstants.BLACK);
delegate.rectangle(10, 10, 300, 300);
delegate.fill();
return this;
}
// "Boring" methods - just delegate the implementation to the wrapped instance
#Override
public PdfCanvas beginVariableText() {
delegate.beginVariableText();
return this;
}
#Override
public PdfCanvas endVariableText() {
delegate.endVariableText();
return this;
}
// Override all other members like above
}
In this case your custom text renderer will only plug in the right DrawContext but use the default draw operation:
private static class CustomTextRenderer extends TextRenderer {
public CustomTextRenderer(Text textElement) {
super(textElement);
}
#Override
public void draw(DrawContext drawContext) {
DrawContext newContext = new DrawContext(drawContext.getDocument(), new PdfCanvasWrapper(drawContext.getCanvas()));
super.draw(newContext);
}
#Override
public CustomTextRenderer getNextRenderer() {
return new CustomTextRenderer((Text) modelElement);
}
}
Main could could look like this:
Paragraph p = new Paragraph();
Text text = new Text("Hello");
text.setTextRenderingMode(TextRenderingMode.CLIP);
text.setNextRenderer(new CustomTextRenderer(text));
p.add(text);
In general this approach is also hacky and of course depends on the implementation details as much as the initial approach you suggested. The approach you suggested is a more stable one but requires more code and probably more tuning when you update to the new version of the library. The approach I described above is more hacky but it results in less business logic copy-pasting and maybe easier to maintain.
I am making my first learning steps with CN1 graphics.
I encounter difficulties when calling the paint method of the following class in the start () method.
public class DrawingCanvas extends Component {
public void myMethod(Graphics g) {
// some code
}
}
In the start() method, I call the method like this:
public void start() {
DrawingCanvas drawingCanvas = new DrawingCanvas();
drawingCanvas.myMethod(g);
}
The error message I get is : Cannot find symbol : variable g
In my understanding, I now have to define g somehow.
How do I do that?
Graphics g =
You can't and don't initialize graphics. Graphics is created internally within Codename One and passed to the paint method as a callback. You should never invoke paint(Graphics) on your own.
If you want to invoke paint(Graphics) you can invoke cmp.repaint() which will call paint for you. Notice that you don't need to invoke it normally as paint is implicitly invoked when needed e.g. when layout changes etc.
I'm trying to add a label to a PolylineConnection in Draw2d. I'm using the example in java2s as a basis. The problem is that even if I can create the text by using graphics.drawText() on the paintFigure method from the PathFigure object (that extends PolylineConnection), the label is cut out most of the time, as shown in these captures:
To me, it looks like the bounds of the figure are leaving part of the text outside from the paint area, as it does indeed paint correctly in diagonal arrows, which have bigger bounds.
I have tried to set explicitly the bounds of the object, both in constructor and paint methods, but it seems like the PolylineConnection is ignoring them. Any idea of how to solve this or if there is another way of achieving this kind of label?
Please use below figure for your connection figure.
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MidpointLocator;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
public class LabelConnectionFigure extends PolylineConnection {
protected Label label;
public LabelConnectionFigure() {
setTargetDecoration(new PolygonDecoration());
MidpointLocator labelLocator = new MidpointLocator(this, 0);
label = new Label("1");
label.setOpaque(true);
add(label, labelLocator);
}
public void setLabelText(String labelText) {
label.setText(labelText);
}
public String getLabelText() {
return label.getText();
}
}
I was coding a very simple program that lets you move around a circle, with also a rectangle in the stage. I wanted to make the circle get in front of the rectangle while you are dragging it, but when you released the mouse, the circle would be sent back.
I don't know how to set a public variable using the getChildIndex method. I don't really care about the rest of the code. I'm mainly interested in how can I make the getChildIndex method work with a public variable.
package code
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.Sprite;
public class Main extends MovieClip
{
public var myCircleIndex:int = getChildIndex(myCircle);
public function Main()
{
myCircle.addEventListener(MouseEvent.MOUSE_DOWN, mouseClicking);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
}
public function mouseClicking(e:MouseEvent): void
{
myCircle.startDrag();
setChildIndex(myCircle, numChildren-1);
}
public function mouseReleased(e:MouseEvent): void
{
myCircle.stopDrag();
setChildIndex(myCircle, myCircleIndex);
}
}
}
I'm using an instance ("myCircle") that I created directly in the stage as a movie clip.
The problem is in the public var I set at the beginning, it doesn't let me get the child index of myCircle, but if I put the same line inside a function, it works.
I know I could directly put the index number of myCircle in the last line (and erasing the public var myCircleIndex), but I figured out that there would be a way of using the getChildIndex for a public var in a class.
How do you use getChildIndex in a public variable inside a class?
The reason it doesn't work, is because your timeline objects don't yet exist when the line public var myCircleIndex:int runs.
You shouldn't try and access non-primitive objects in your class level variable declarations for this very reason, as nothing else in the class is available yet when those vars are created.
Here is how you can refactor this (see the code comments):
public class Main extends MovieClip
{
public var myCircleIndex:int; //just create the reference here, don't assign it
public var myCircle:flash.display.DisplayObject; //this line is just for better compile time checking and code completion, completely optional
public function Main()
{
//wait for all the display stuff to be created before trying to access it. The constructor function can run before timeline stuff is created, so it's not safe to reference stage or timeline objects here.
if(!stage){
this.addEventListener(Event.ADDED_TO_STAGE, timelineCreated);
}else {
timelineCreated(null);
}
}
private function timelineCreated(e:Event):void {
//now that we're certain the timeline stuff has been created, we can reference timeline objects and stage:
//store the initial z-index of myCircle
myCircleIndex = getChildIndex(myCircle);
//the rest of your code that was in the construction -Main()- before
myCircle.addEventListener(MouseEvent.MOUSE_DOWN, mouseClicking);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
}
//no change to any of the following stuff
public function mouseClicking(e:MouseEvent): void
{
myCircle.startDrag();
setChildIndex(myCircle, numChildren-1);
}
public function mouseReleased(e:MouseEvent): void
{
myCircle.stopDrag();
setChildIndex(myCircle, myCircleIndex);
}
}
All you need to do to put the circle behind the square is on release do addChild(myRectangle) or addChildAt(myCircle, 0);
You are overcomplicating things by trying to track a variable in my opinion. Let flash sort it out behind the scenes.
If you want a little more finesse and want to just put the circle directly behind the square (if there were 100 layers and the square is at level 12, but you aren't sure which level the square is at) you could do
addChildAt(myCircle, getChildIndex(myRectangle)-1);
note
setChildIndex(myCircle, numChildren-1);
That's fine to do it that way. The more common way to do this is just
addChild(myCircle);
It does the exact same thing. Many people are confused by this thinking this would add a new myCircle but it just brings it to the front if it's already in the display list, and if it's not in the display list, it adds it to the display list at the top z-order (numChildren-1).
How can I fill my implemented interface width the Object it brings width.
public class MegaPlayer implements Player{
public MegaPlayer(Player player){
(?here do I need help?) = player;
I like to set the data for the object Player width one step otherwise I have to set any Information separately