I'm not really sure if i have understood the principe of the DataFlavors correctly, but how can i actually set the DataFlavor(s) of a JComponent?
Every time i call the getDataFlavor method the output is this:
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-file-list;representationclass=java.util.List]
My problem is, that i want to drag images from the desktop or any other place right into my JPanel. It's working through the DataFlavor.javaFileListFlavor, but is there no way that i can create a custom flavor which only accepts PNG and JPG Files for example?
(I know that it is actually possible to create Custom Flavors but i have no clue how i can "enable" the new created flavors for my components)
Or is there a way to ensure whether the dragged in Item is a PNG or JPG with the javaFileListFlavor?
I hope that i could explain my question well enough (I'm not a master of this language, but i'm trying my best ;) )
Or is there a way to ensure whether the dragged in Item is a PNG or JPG with the javaFileListFlavor?
Take a look at the Swing tutorial on Top Level Drop. It shows how to drag a file from the desktop to a JTextArea.
Take a look at the canImport(...) and importData(...) methods of the TransferHandler. The canImport(...) method currently only checks that you have a FileListFlavor. So you would need to add extra logic to see the actual File is a PNG or JPG.
If you look at the importData(...) method you can see how to get the File object from the TransferSupport object so you can implement the above check.
Edit:
but as described the Exception pops up
I just ignore the Exception. Here is the modified code for the tutorial that only allows your to copy ".java" files into the text area.
private TransferHandler handler = new TransferHandler() {
public boolean canImport(TransferHandler.TransferSupport support) {
if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
Transferable t = support.getTransferable();
try
{
java.util.List<File> l = (java.util.List<File>)t.getTransferData(DataFlavor.javaFileListFlavor);
File file = l.get(0);
String fileName = file.getName();
if (!file.getName().endsWith(".java"))
return false;
}
catch (Exception e)
{
// ignore
}
if (copyItem.isSelected()) {
boolean copySupported = (COPY & support.getSourceDropActions()) == COPY;
if (!copySupported) {
return false;
}
support.setDropAction(COPY);
}
return true;
}
Works fine for me using JDK8 on Winodow 7.
Related
I would like to know how to choose the block that my TNT be placed on. Here is my code.
ItemStack tnt = new ItemStack(Material.TNT, 1);
As in give #p tnt 1 0 {PlaceOn:emerald_block}.
I am using Spigot for Minecraft 1.12 and Eclipse.
There is no way to do that via the Spigot API natively, you need to use NMS and NBT:
net.minecraft.server.v1_12_R1.ItemStack stack = CraftItemStack.asNMSCopy(tnt);
NBTTagList tags = (NBTTagList) stack.getTag().get("CanPlaceOn");
if (tags == null)
tags = new NBTTagList();
tags.add(new NBTTagString("minecraft:emerald_block"));
stack.getTag().set("CanPlaceOn", tags);
ItemStack toUse = CraftItemStack.asCraftMirror(stack);
Generally speaking if you can avoid using NMS you should, and there is a pretty easy way to do this. Whenever a block is placed by a player, a BlockPlaceEvent is called by the server. If you are unsure how they work, look here: http://bukkit.gamepedia.com/Event_API_Reference.
An example of how to handle this behavior is below:
public void onBlockPlace(BlockPlaceEvent e) {
if (e.getBlockPlaced().getType() == Material.TNT) {
Material belowType = e.getBlockPlaced().getRelative(BlockFace.DOWN).getType();
// your code here...
}
}
This code allows you to check if the block that is placed is TNT, then it retrieves the type of the block directly below it.
Hope this helps!!
I have been attempting to program a solution for ImageJ to process my images.
I understand how to get a directory, run commands on it, etc etc. However I've run into a situation where I now need to start using some type of search function in order to pair two images together in a directory full of image pairs.
I'm hoping that you guys can confirm I am on the right direction and that my idea is right. So far it is proving difficult for me to understand as I have less than even a month's worth of experience with Java. Being that this project is directly for my research I really do have plenty of drive to get it done I just need some direction in what functions are useful to me.
I initially thought of using regex but I saw that when you start processing a lot of images (especially with imagej which it seems does not dump data usage well, if that's the correct way to say it) that regex is very slow.
The general format of these images is:
someString_DAPI_0001.tif
someString_GFP_0001.tif
someString_DAPI_0002.tif
someString_GFP_0002.tif
someString_DAPI_0003.tif
someString_GFP_0003.tif
They are in alphabetical order so it should be able to go to the next image in the list. I'm just a bit lost on what functions I should use to accomplish this but I think my overall while structure is correct. Thanks to some help from Java forums. However I'm still stuck on where to go to next.
So far here is my code: Thanks to this SO answer for partial code
int count = 0;
getFile("C:\");
string DAPI;
string GFP;
private void getFile(String dirPath) {
File f = new File(dirPath);
File[] files = f.listFiles();
while (files.length > 0) {
if (/* File name contains "DAPI"*/){
DAPI = File f;
string substitute to get 'GFP' filename
store GFP file name into variable
do something(DAPI, GFP);
}
advance to next filename in list
}
}
As of right now I don't really know how to search for a string within a string. I've seen regex capture groups, and other solutions but I do not know the "best" one for processing hundreds of images.
I also have no clue what function would be used to substitute substrings.
I'd much appreciate it if you guys could point me towards the functions best for this case. I like to figure out how to make it on my own I just need help getting to the right information. Also want to make sure I am not making major logic mistakes here.
It doesn't seem like you need regex if your file names follow the simple pattern that you mentioned. You can simply iterate over the files and filter based on whether the filename contains DAPI e.g. see below. This code may be oversimplification of your requirements but I couldn't tell that based on the details you've provided.
import java.io.*;
public class Temp {
int count = 0;
private void getFile(String dirPath) {
File f = new File(dirPath);
File[] files = f.listFiles();
if (files != null) {
for (File file : files) {
if (file.getName().contains("DAPI")) {
String dapiFile = file.getName();
String gfpFile = dapiFile.replace("DAPI", "GFP");
doSomething(dapiFile, gfpFile);
}
}
}
}
//Do Something does nothing right now, expand on it.
private void doSomething(String dapiFile, String gfpFile) {
System.out.println(new File(dapiFile).getAbsolutePath());
System.out.println(new File(gfpFile).getAbsolutePath());
}
public static void main(String[] args) {
Temp app = new Temp();
app.getFile("C:\\tmp\\");
}
}
NOTE: As per Vogel612's answer, if you have Java 8 and like a functional solution you can have:
private void getFile(String dirPath) {
try {
Files.find(Paths.get(dirPath), 1, (path, basicFileAttributes) -> (path.toFile().getName().contains("DAPI"))).forEach(
dapiPath -> {
Path gfpPath = dapiPath.resolveSibling(dapiPath.getFileName().toString().replace("DAPI", "GFP"));
doSomething(dapiPath, gfpPath);
});
} catch (IOException e) {
e.printStackTrace();
}
}
//Dummy method does nothing yet.
private void doSomething(Path dapiPath, Path gfpPath) {
System.out.println(dapiPath.toAbsolutePath().toString());
System.out.println(gfpPath.toAbsolutePath().toString());
}
Using java.io.File is the wrong way to approach this problem. What you're looking for is a Stream-based solution using Files.find that would look something like this:
Files.find(dirPath, 1, (path, attributes) -> {
return path.getFileName().toString().contains("DAPI");
}).forEach(path -> {
Path gfpFile = path.resolveSibling(/*build GFP name*/);
doSomething(path, gfpFile);
});
What this does is:
Iterate over all Paths below dirPath 1 level deep (may be adjusted)
Check that the File's name contains "DAPI"
Use these files to find the relevant "GFP"-File
give them to doSomething
This is preferrable to the files solution because of multiple things:
It's significantly more informative when failing
It's cleaner and more terse than your File-Based solution and doesn't have to check for null
It's forward compatible, and thus preferrable over a File-Based solution
Files.find is available from Java 8 onwards
I have a JList that is displaying a custom object (Frog) using a custom cell renderer.
frogList = new JList<Frog>();
frogModel = new DefaultListModel<Frog>();
frogList.setModel(frogModel);
frogList.setCellRenderer(new FrogBrowserCellRenderer());
//add frogs...
The frog objects contains a list of images, and I have my list pick the latest one to display. It's in a thumbnail file, so I can read it into memory and display it. However I know that the JList re-renders every time the window moves or the window needs redrawn which is really bad for performance and just not good design. The issue I have is that this list is dynamic so I cannot simply load all images at startup because users can add them at runtime and it'll auto update the list.
Some people mentioned loading the image into memory in the constructor and setting it in the getListCellRendererComponent() method but that doesn't appear to be possible because it only creates one cell renderer and uses it for everything in the list. I also verified this by printing out the constructor method. Since I will have a list of frogs with all different images this doesn't really make sense.
Here is the code I am using to create the thumbnail right now.
public Image createListThumbnail() {
try {
Image returnImg = null;
//get latest frog image
SiteImage img = frog.getLatestImage();
BufferedImage src = ImageIO.read(new File(XMLFrogDatabase.getImagesFolder()+img.getImageFileName()));
BufferedImage thumbnail = Scalr.resize(src, Scalr.Method.SPEED, Scalr.Mode.FIT_TO_WIDTH, 200, 150, Scalr.OP_ANTIALIAS);
if (!frog.isFullySearchable()){
ImageFilter filter = new GrayFilter(true, 30);
ImageProducer producer = new FilteredImageSource(thumbnail.getSource(), filter);
returnImg = Toolkit.getDefaultToolkit().createImage(producer);
}
return returnImg;
} catch (IOException e) {
IdentiFrog.LOGGER.writeExceptionWithMessage("Unable to generate thumbnail for image (in memory).", e);
}
return null;
}
I call this method in my getListCellRendererComponent() which I know causes terrible performance but I don't understand how to cache it in memory for multiple frogs and also use only one object. Perhaps an image map? I can't seem to find any solid evidence of a proper way to do this.
I write a multiplatform logic game, that will have to work in all modes: Java, JS and Android. I need to do some things different in all modes (especially, but not limited to, storage, for Java/Android I want to use load/saveTable and for JS - localStorage).
To do that I need to get the information, which is the mode the sketch runs. And I need to do this in runtime, just to avoid keeping different source for all platforms.
I was looking in the docs but found nothing in the topic. My Google research also led me to thoughts, that nobody even asked for that...
I was thinking about using try/catch to check some functions that exist in Java but not in JS, but this seems to be rather unelegant and whatismore I can not find the propper way for that.
What I have found is:
try {
PApplet a;
a = new PApplet();
mode = "JAVA";
}
catch(Throwable e) {
mode = "JS";
}
This distinguishes Java and JavaScript, but can not recognize Android...
So to summarize - what's the best way to distinguish, whether I run the sketch in JS or Java mode on runtime?
Ok, I have found quite nice way with try/catch:
String mode;
mode = "unknown";
try {
java.lang.Object a;
a = new java.lang.Object();
mode = "JAVA";
}
catch(Throwable e) {
mode = "JS";
}
This distinguishes JavaScript from the Java/Android but can not distinguish Android from Java. But since the differences are minimal this not causes significant problems with compatibility to me.
If someone knows the way to do this better - please post your answer!
I figured out how to detect Java vs. Android mode. Kind-of a hack:
import java.lang.reflect.*;
Method getInternalProcessingMethod(String methodName) {
/*
* Helper method that can be used to return
* an internal processing method by name
*/
Class cls = this.getClass();
try {
return cls.getMethod(methodName);
} catch (Exception e) {
return null;
}
}
boolean isAndroidMode() {
/*
* Determine if we're running in Android mode or not
*/
// What?
// In Android mode 'displayDensity' is a field and in Java
// mode 'displayDensity' is a method. This is a hack...but
// it works.
if (getInternalProcessingMethod("displayDensity") == null) {
return true;
}
return false;
}
And then you can use this to do something like what I use it for:
void settings() {
IS_ANDROID_MODE = isAndroidMode();
if (IS_ANDROID_MODE) {
println("Android mode detected");
fullScreen();
SAVE_LOCATION = "blah.json";
} else {
println("Java mode detected");
size(600, 1233);
SAVE_LOCATION = "data/blah.json";
}
}
Now I can have my test app run on my desktop in a small window but then run fullscreen with a different save file path on Android.
I've implemented a MatchPage which displays the following informations:
MatchStatus (OPEN/CLOSED)
Winner (Name of the Winner)
Form to upload files
(follow the link to see how it looks like, [1]: http://www10.pic-upload.de/25.04.13/klmy9fe8cgk3.png)
Now here comes the problem. Let's assume, someone is reporting a result while another one has currently open the specific MatchPage. When the report is done, the MatchStatus will change from OPEN to CLOSED, the color will change from OPEN=green to CLOSED=red, the Winner will be set and the Form for uploading files will disappear (see [2]: http://www7.pic-upload.de/25.04.13/9diu5bcbws9.png).
The player who reported the result will see the updated MatchPage while the other one will still see the old version of the MatchPage, even if he refreshed the browser.
I could solve the problem with OPEN/CLOSED by using my own LoadableDetachableModel:
#Override
public String load()
{
Match m = dao.getMatchFromID(match_id);
String result = "OPEN";
if (m.getClosed())
{
result = "CLOSED";
reportForm.setVisible(false); //does not work
colorBehavior.setColor("red"); //does not work
}
return result;
}
Label on my MatchPage:
matchStatus = new Label("matchStatus", new MyMatchModel(m.getMatch_id(), matchDAO, reportForm));
As you can see on the load() method, setting the reportForm invisible and setting the color to red does not work.
Any idea how i can solve such kind of problem? How can i make the form disappear and change the color to red when the user pressed F5/refresh the browser.
You should override the "isVisible()" method of the form like this:
public boolean isVisible() {
return !yourModel.getObject().getClosed();
}