How do I stop JFreechart from unzooming when I drag left?
thxs.
I made an assumption (based on your short question) that you want to disable the "zoom restore" feature when invoked by the mouse being dragged to the left.
If so, you simply need to override the restoreAutobounds() method like this:
JFreeChart chart = /* create your chart here*/
// add the chart to the panel and override
// the zoom restore behavior
chartPanel = new ChartPanel(chart){
#Override
public void restoreAutoBounds(){
// Do nothing
}
};
Or, event better is to extend the ChartPanel object and override it there.
NOTE: the zoom out feature will still be available from the context menu of the chart so the user still has meaningful ways to zoom out
Related
I am trying to implement a "stamping" feature. I am selecting an image from a list, and using it to stamp on the clicked position on my canvas.
I have read several solutions on how to change the cursor, but they involved simply changing the ico texture.
I want to be able to preview in real time what I will be stamping. So if I change the rotation of the stamp, the cursor needs to rotate appropriately, if I scale the stamp the cursor needs to be scaled, and if I switch the stamp the cursor needs to switch.
I tried adding an image to an observablecollection, and binding it to the canvas. Then I tried updating the position, image, scale inside the MouseMove event of the canvas, but it doesnt work.
Here is the MouseMove function:
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (currentTool == "staticBrush" && lvDataBinding.SelectedIndex != -1)
{
canvasImages[0].Name = srcImages[lvDataBinding.SelectedIndex].Name;
canvasImages[0].BmpImage = new BitmapImage(new Uri(canvasImages[0].Name, UriKind.Relative));
scale(canvasImages[0]);
canvasImages[0].OffsetX = e.GetPosition(canvasDataBinding).X;
canvasImages[0].OffsetY = e.GetPosition(canvasDataBinding).Y;
}
}
You have two main options... you can either follow a fairly complex tutorial such as WPF Tutorial - How To Use Custom Cursors on TechPro, which should enable you to create a Cursor from just about any WPF UIElement, or you can simply hide the Cursor by setting Cursor = Cursors.None and replacing it with your own Image... of course, with this method, you'd also be responsible for moving the Image wherever the mouse cursor moves.
This may sound very basic as a question, but i am stuck in JFreechart use.
Let me lay out my problem :
I have a CombinedDomainXYPlot to which I add my subplots as and when required.
I have used my custom JPopup menu and have included a menu item that is intended to provide user the facility to delete a particular subplot
I am assuming that one can find a subplot using findSubplot method of the main plot. I am able to get mouse positions but not able to do anything with PlotRenderingInfo that's required as input.
Would appreciate some help.
You can get a List of subplots using getSubplots(). To learn which subplot was clicked, examine the ChartMouseEvent that was sent from the ChartPanel, as suggested here.
Addendum: Here's a simple implementation of ChartMouseListener that will show each ChartEntity as it is clicked.
ChartPanel panel = ...
panel.addChartMouseListener(new ChartMouseListener() {
#Override
public void chartMouseClicked(ChartMouseEvent e) {
System.out.println(e.getEntity().getClass());
}
#Override
public void chartMouseMoved(ChartMouseEvent event) {}
});
I have a panel and on that I've a picturebox. There are around 20 labels that I've to show in the panel. I want the background of Label to be transparent ie the image in picturebox is shown and the label displays only the text.
Now since labels do not exhibit true transparency I made the labels child of picturebox
this.lbl1.Parent = pictureBox1;
This has solved my immediate problem but now when the form loads, all the labels take a while to become visible and do so one at a time. I'd appreciate if you guys can give some solution for this.
Thanks in advance
The standard cure for flicker is double-buffering. But that cannot solve this kind of flicker. It is a different kind, caused by having multiple windows overlapping each other. Each label is its own window. When the form needs to paint itself, it draws its background leaving holes for the child windows. Each child window then takes a turn drawing itself. And their child windows draw themselves next. Etcetera.
This becomes noticeable when one control takes a while to draw, no doubt your picture box. Especially when it displays a large image that needs to be resized. The holes for the child windows stay unpainted while the picture box draws. They have a white background, black when you use the form's TransparencyKey or Opacity property. This can contrast badly with the image in your picture box, that effect is perceived by the user as flicker.
One immediate cure is to not use controls so you don't pay for their window. A Label is very convenient but it is a massive waste of system resources to burn up a window just to display a string. You can simply implement the picture box' Paint event and draw the strings with TextRenderer.DrawText(). PictureBox has double-buffering turned on by default so the image as well as the text is drawn completely smoothly, no more flicker. The obvious disadvantage is that you lose the convenience of point-and-click, you have to write code.
There are other fixes possible. One of them is to prevent the picture box from leaving holes for the child windows. It will draw the entire image, the labels pop on top of them. That's still flicker but not nearly as noticeable. Add a new class to your project and paste this code:
using System;
using System.Windows.Forms;
internal class MyPictureBox : PictureBox {
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
}
Compile and drop the new picture box control from the top of the toolbox onto your form.
Yet another possible workaround is to make the form and all of its children double-buffered. This doesn't speed up the painting at all but all of the windows get rendered into a memory buffer, the result is blitted to the screen. You'll notice a delay but the window suddenly pops on the screen. This is called compositing. Winforms doesn't support this directly since it can have side-effects but it is easy to enable. Paste this code into your form class:
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Supported by XP and later. Watch out for painting artifacts.
or you can ditch the labels and draw the text yourself:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
TextRenderer.DrawText(e.Graphics, "Label1", SystemFonts.DefaultFont,
new Point(10, 10), Color.Black, Color.Empty);
}
The label does not support transparency, you must create your own unique custom control, you can see these code examples.
http://www.codeproject.com/KB/dotnet/transparent_controls_net.aspx http://www.codeproject.com/KB/vb/uLabelX.aspx
Bye
I am developing an kind of outlook calendar application where I need to make the appointment resizable from mouse.
My first try with a thumb did not work properly so I tried another way.
What I did is that:
1) on the botton of the appointmennt panel I added a rectangle to figure out the resize zone (the thumb). The appointment panel is put on a grid panel.
2) I intercept down event on the rectangle and send event to this code:
private Point startPoint;
private void OnResizeElementMouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
this.MouseMove += new MouseEventHandler(ResizeEndElement_MouseMove);
this.MouseLeftButtonUp += new MouseButtonEventHandler(OnResizeElementMouseUp);
// some code to perform new height computation
Mouse.Capture(this);
}
where this is the appointment panel that own the thumb.
Decreasing height works well.
But increasing is more difficult. If I move the mouse very very slowly it's OK, if I speed it up a little bit it tends to leave out the appointment panel and then all MouseMove event are lost.
I thought Mouse.Capture() was propose to solve this kind of problem, but in fact not.
Does anybody know what is wrong in my code?
You should be using an actual Thumb control. Check out MSDN for help:
How to: Use a Thumb to Enable Dragging
you should use a thumb, but to play with mouse capture, override the protected override void OnLostMouseCapture(MouseEventArgs e) method, then you will know if you have lost the capture.
I need a way to distinguish when a mouse event occurs in the chart itself and not in the chartPanel (the plot area).
Thanks
You should be able to use the mouse event from your panel and use ChartMouseEvent.getEntity() to find if your chart is over one of the chart entities. See the api docs for ChartMouseEvent.