Copy/paste connected shape in Acrobat Reader

Adobe Acrobat Reader DC has a “shape” called “Connected Lines” in the comments pane. I wanted to copy/paste and move one around. This was a pain in the neck. I wasn’t expecting it to be that hard.

I ran into three problems:

1 – Pasting only works in a certain mode

I select the shape with ctrl-C. If I press ctrl-v to paste, nothing happens. Why? Apparently because I have the comment feature open. If I open the stamp feature or click “close” so nothing is open, it does paste. Ok fine. Except…

2 – It doesn’t paste where I put the mouse cursor

When I get it to paste, it always seems to be the center middle of the screen towards the bottom. This is rarely where I want my pasted item. This would be a minor annoyance except

3. It doesn’t let me drag with the mouse

A text comment box, I can select with my mouse and drag where I want it. A connected shape changes the shape when I try to select it. I can use the arrow keys to move it but that is slow and tedious… Oh wait. I figured it out. If I mouse over very carefully to the center of the connected shape, my mouse turns into a drag icon and I can drag it with my mouse.

Update: Java 11 Practice Tests

Jeanne and I know many of our readers are anxiously awaiting their copy of our new Java OCP 11 Practice Test Book for the 1Z0-819 Exam, originally expected out this month. The good news is we finished the manuscript a few months ago, so the book is done! The bad news is, the publishing and printing process has been slower than expected given everything going on in the world.

We now expect the book to be available in late January/early February. Believe us, no one is more anxious for this book than us! If you purchase the book from Amazon or other resellers, it will ship as soon as it is available!

Oh, and a big thanks to all our readers this year, whose feedback and support has kept us going in these strange times!

Multi statement lambda and for each anti patterns

When I do a code review of lambda/stream code, I am immediately suspicious of two things – block statement lambdas and forEach().

What’s wrong with this? It’s functional programming right?

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
		
AtomicInteger sum = new AtomicInteger();
List<Integer> odds = new ArrayList<>();
List<Integer> evens = new ArrayList<>();
		
list.forEach(n -> {
	sum.addAndGet(n);
	if (n % 2 == 0) {
		evens.add(n);
	} else {
		odds.add(n);
	}
});
		
odds.forEach(System.out::println);
System.out.println();
evens.forEach(System.out::println);
System.out.println();
System.out.println(sum);

Well? Not really. It does have a lambda. It doesn’t have a stream, but that’s easy enough to fix: list.stream().forEach(…).

All better? No. Just because you are using a stream doesn’t mean you are doing functional programming. I would much rather see this code as:

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
		
		
list.stream()
   .filter(x -> x % 2 == 1)
   .forEach(System.out::println);

System.out.println();

list.stream()
   .filter(x -> x % 2 == 0)
   .forEach(System.out::println);

System.out.println();

list.stream()
   .mapToInt(x -> x)
   .sum();

Yes, I’m still using forEach(). But now I’m using it for one purpose (printing) rather than sticking logic in it.

Whenever I see a forEach() or lambda with more than one statement, my first thought is “could this be clearer or more functional.” Often the answer is yes. Filter(), map() and collect() are you friends.

And if I did need that List?

list.stream()
   .filter(x -> x % 2 == 1)
   .collect(Collectors.toList());